前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >学习KNN(三)KNN+HOG实现手写数字识别

学习KNN(三)KNN+HOG实现手写数字识别

作者头像
chaibubble
发布2018-01-08 10:45:07
1.5K0
发布2018-01-08 10:45:07
举报

学习KNN(一) 图像分类与KNN原理

学习KNN(二)KNN算法手写数字识别的OpenCV实现

学习KNN(三)KNN+HOG实现手写数字识别

学习KNN(二)KNN算法手写数字识别的OpenCV实现我们直接将像素值作为特征,实现了KNN算法的手写数字识别问题,并得到了较好的准确率,但是就像其他机器学习算法一样,KNN的对象同样是特征,所以我们可以用一种特征提取算法配合KNN实现手写数字识别的任务。

下面用HOG原理及OpenCV实现中介绍的HOG算法提取特征,作为KNN的的输入,最后与像素值特征的结果进行对比。

在数据方面还是使用之前生成的5000张手写数字图片,并根据之前介绍的KNN与HOG的OpenCV实现,写出如下代码:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/ml/ml.hpp>  
using namespace std;
using namespace cv;

char ad[128]={0};

int main()
{
    Mat samFeatureMat ,samLabelMat;
    int k=5,testnum=0,truenum=0;
    HOGDescriptor hog(Size(20,20),Size(10,10),Size(2,2),Size(2,2),9);//利用构造函数,给对象赋值。
    int DescriptorDim;//HOG描述子的维数
    //读取训练数据 4000张
    for (int i = 0; i < 10; i++)
    {
        for (int j =0;j<400;j++)
        {
            sprintf_s(ad, "D:\\data\\%d\\%d.jpg",i,j);
            Mat srcimage = imread(ad);
            vector<float> descriptors;//HOG描述子向量
            hog.compute(srcimage,descriptors);

            if ( i == 0&&j==0)
            {
                DescriptorDim = descriptors.size();
                samFeatureMat = Mat::zeros(4000  , DescriptorDim, CV_32FC1);
                samLabelMat = Mat::zeros(4000  , 1, CV_32FC1);
            }

            for(int k=0; k<DescriptorDim; k++)
            {
                samFeatureMat.at<float>(i*400+j,k) = descriptors[k];
                samLabelMat.at<float>(i*400+j,0) = i;
            }
        }
    }
    samFeatureMat.convertTo(samFeatureMat,CV_32F);
    CvKNearest knn( samFeatureMat, samLabelMat, cv::Mat(), false, k );  
    cv::Mat nearests( 1, k, CV_32F);  
    //读取测试数据  1000张
    for (int i = 0; i < 10; i++)
    {
        for (int j =400;j<500;j++)
        {
            testnum++;
            sprintf_s(ad, "D:\\data\\%d\\%d.jpg",i,j);
            Mat testFeatureMat =Mat::zeros(1,DescriptorDim, CV_32FC1);
            Mat testdata = imread(ad);
            vector<float> descriptors;//HOG描述子向量
            hog.compute(testdata,descriptors);
            for(int k=0; k<DescriptorDim; k++)
            {
                testFeatureMat.at<float>(0,k) = descriptors[k];
            }
            testFeatureMat.convertTo(testFeatureMat,CV_32F);
            int  response = knn.find_nearest(testFeatureMat,k,0,0,&nearests,0); 
            if (response==i)
            {
                truenum++;
            }
        }
    }
    cout<<"测试总数"<<testnum<<endl;
    cout<<"正确分类数"<<truenum<<endl;
    cout<<"准确率:"<<(float)truenum/testnum*100<<"%"<<endl;
    return 0;
}

在HOG特征提取时,我们将整张图片作为一个检测窗,并设置块尺寸为10*10,块步长为(2,2),cell尺寸为2*2,bin个数为9,那么计算一下描述子维数就是:

    一个检测窗口中可以滑出36个块,一个块中可以划分25个cell,一个cell中产生9个方向,那么36\*25\*9=8100。

最后,结果统计如下所示:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-09-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档