OpenCV手写数字字符识别(基于k近邻算法)

简介:   摘要 本程序主要参照论文,《基于OpenCV的脱机手写字符识别技术》实现了,对于手写阿拉伯数字的识别工作。识别工作分为三大步骤:预处理,特征提取,分类识别。预处理过程主要找到图像的ROI部分子图像并进行大小的归一化处理,特征提取将图像转化为特征向量,分类识别采用k-近邻分类方法进行分类处理,最后根据分类结果完成识别工作。

 

摘要

本程序主要参照论文,《基于OpenCV的脱机手写字符识别技术》实现了,对于手写阿拉伯数字的识别工作。识别工作分为三大步骤:预处理,特征提取,分类识别。预处理过程主要找到图像的ROI部分子图像并进行大小的归一化处理,特征提取将图像转化为特征向量,分类识别采用k-近邻分类方法进行分类处理,最后根据分类结果完成识别工作。

程序采用Microsoft Visual Studio 2010与OpenCV2.4.4在Windows 7-64位旗舰版系统下开发完成。并在Windows xp-32位系统下测试可用。

主流程图

 

细化流程图:

 

 

 

1.   预处理

预处理的过程就是找到图像的ROI区域的过程,如下图所示:

 

首先找到数字的边界框,然后大小归一化数字图片,主要流程如下图所示:

 

 

 

主要代码:

IplImagepreprocessing(IplImage*imgSrc,intnew_width,intnew_height)

{

       IplImage* result;

       IplImage* scaledResult;

 

       CvMat data;

       CvMat dataA;

      CvRectbb;//bounding box

      CvRectbba;//boundinb box maintain aspect ratio

      

      //Find bounding box找到边界框

       bb=findBB(imgSrc);

       cvGetSubRect(imgSrc, &data,cvRect(bb.x,bb.y,bb.width,bb.height));

       int size=(bb.width>bb.height)?bb.width:bb.height;

       result=cvCreateImage( cvSize( size, size ), 8, 1 );

       cvSet(result,CV_RGB(255,255,255),NULL);

      //图像放中间,大小归一化

       int x=(int)floor((float)(size-bb.width)/2.0f);

       int y=(int)floor((float)(size-bb.height)/2.0f);

       cvGetSubRect(result, &dataA,cvRect(x,y,bb.width,bb.height));

       cvCopy(&data, &dataA,NULL);

      //Scale result

       scaledResult=cvCreateImage( cvSize( new_width, new_height ), 8, 1 );

       cvResize(result, scaledResult, CV_INTER_NN);

      

      //Return processed data

      return *scaledResult;//直接返回处理后的图片

      

}

 

 

2.   特征提取

在拿到ROI图像减少了信息量之后,就可以直接用图片作为向量矩阵作为输入:

voidbasicOCR::getData()

{

       IplImage* src_image;

       IplImage prs_image;

       CvMat row,data;

       char file[255];

       int i,j;

       for(i =0; i<classes;i++)//总共10个数字

       {

             for(j = 0; j<train_samples;j++)//每个数字50个样本

              {

                    

                    //加载所有的样本pbm格式图像作为训练

                    if(j<10)

                           sprintf(file,"%s%d/%d0%d.pbm",file_path,i,i , j);

                    else

                           sprintf(file,"%s%d/%d%d.pbm",file_path,i,i , j);

                    src_image =cvLoadImage(file,0);

                    if(!src_image)

                     {

                           printf("Error: Cant load image %s\n",file);

                           //exit(-1);

                     }

                    //process file

                    prs_image =preprocessing(src_image,size,size);

                    //生成训练矩阵,每个图像作为一个向量

                    cvGetRow(trainClasses, &row,i*train_samples +j);

                    cvSet(&row,cvRealScalar(i));

                    //Set data

                    cvGetRow(trainData, &row,i*train_samples +j);

 

                    IplImage*img = cvCreateImage(cvSize( size, size ),

IPL_DEPTH_32F, 1 );

                    //转换换 8 bits image to 32位浮点数图片取值区间为[0,1]

                    //scale = 0.0039215 = 1/255; 

                    cvConvertScale(&prs_image,img, 0.0039215, 0);

 

                    cvGetSubRect(img, &data,cvRect(0,0,size,size));

                    

                    CvMatrow_header, *row1;

                    //convert data matrix sizexsize to vecor

                    row1 =cvReshape( &data, &row_header, 0, 1 );

                    cvCopy(row1, &row,NULL);

              }

       }

}

 

 

3.   分类识别

识别方法采用knn近邻分类法。这个算法首先贮藏所有的训练样本,然后通过分析(包括选举,计算加权和等方式)一个新样本周围K个最近邻以给出该样本的相应值。这种方法有时候被称作“基于样本的学习”,即为了预测,我们对于给定的输入搜索最近的已知其相应的特征向量。

K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

识别工作主要有以下几个步骤:

1. 初始化机器学习算法,及其训练

knn=new CvKNearest( trainData, trainClasses, 0, false, K );

因为trainData, trainClasses数据已得到。训练在CvKNearest算法初始化中已经完成

2. 识别

获取识别测试的数据,testData

result=knn->find_nearest(testData,K,0,0,nearest,0);

result为返回的识别的结果

 

 

4.   实验结果

在knn参数k=5,子图像向量大小选取128*128像素,训练样本50副图片,测试样本50副图片,系统误识率为7.4%。对于用户手写阿拉伯数字2的识别结果为2,识别比较准确。

 

 

 

5.   未来的工作

本程序主要参照网上的一些实例完成了部署跟实验工作,虽然仅仅完成了手写阿拉伯数字的识别工作,但是字符识别的一些原理工作都是相同的,未来能够从一下几个方面进行提高:

1.      提高程序的识别准确率,从一些文献实现的结果来看,简单的模型结合大量的训练样本,往往效果比复杂的模型结合少量训练样本实现的效果好。

2.      扩展程序的功能,从实现简单的字符到最终实现识别手写汉字等。

3.      提高识别速度,改进算法为并行算法,实现如联机在线识别等。

 

 

6.主要参考文献:

http://blog.csdn.net/jackmacro/article/details/7026211

http://blog.damiles.com/2008/11/basic-ocr-in-opencv/

http://blog.csdn.net/zhubenfulovepoem/article/details/6803150

http://blog.csdn.net/firehood_/article/details/8433077

http://blog.csdn.net/viewcode/article/details/7943341

 

 

7.项目打包下载

http://download.csdn.net/detail/wangyaninglm/6631953

 

8.手写字符识别的复杂版本,这个增加了一些OpenGL技术,程序比较复杂

http://blog.csdn.net/wangyaninglm/article/details/41848019

相关文章
|
28天前
|
算法 前端开发 数据处理
小白学python-深入解析一位字符判定算法
小白学python-深入解析一位字符判定算法
45 0
|
3月前
|
算法
【算法】位运算算法——判断字符是否唯一
【算法】位运算算法——判断字符是否唯一
|
3月前
|
算法
【算法】滑动窗口——无重复字符的最长子串
【算法】滑动窗口——无重复字符的最长子串
|
1月前
|
机器学习/深度学习 算法
机器学习入门(三):K近邻算法原理 | KNN算法原理
机器学习入门(三):K近邻算法原理 | KNN算法原理
|
1月前
|
机器学习/深度学习 算法 API
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
|
28天前
|
算法 计算机视觉 Python
圆形检测算法-基于颜色和形状(opencv)
该代码实现了一个圆检测算法,用于识别视频中的红色、白色和蓝色圆形。通过将图像从RGB转换为HSV颜色空间,并设置对应颜色的阈值范围,提取出目标颜色的区域。接着对这些区域进行轮廓提取和面积筛选,使用霍夫圆变换检测圆形,并在原图上绘制检测结果。
62 0
|
3月前
|
算法 定位技术 vr&ar
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
444 0
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
|
3月前
|
机器学习/深度学习 存储 并行计算
C语言与机器学习:K-近邻算法实现
C语言与机器学习:K-近邻算法实现
57 0
|
4月前
|
存储 传感器 算法
「AIGC算法」近邻算法原理详解
**K近邻(KNN)算法概述:** KNN是一种基于实例的分类算法,依赖于训练数据的相似性。算法选择最近的K个邻居来决定新样本的类别,K值、距离度量和特征归一化影响性能。适用于非线性数据,但计算复杂度高,适合小数据集。应用广泛,如推荐系统、医疗诊断和图像识别。通过scikit-learn库可实现分类,代码示例展示了数据生成、模型训练和决策边界的可视化。
40 0
「AIGC算法」近邻算法原理详解
|
5月前
|
机器学习/深度学习 存储 算法
K 近邻算法(二)
K-近邻(KNN)算法是一种监督学习方法,用于分类和回归。关键步骤包括计算新样本与训练样本的距离,选择合适的邻近样本数K,基于K个邻居的多数类别或平均值做出预测。K值的选择影响模型性能:小K易受噪声影响(过拟合),大K可能导致模型过于简单(欠拟合)。评估模型通常使用测试集的预测准确率,如sklearn.metrics.accuracy_score。最优K值可通过交叉验证,如GridSearchCV,来确定,但它可能计算密集。KNN常用于手写数字识别等任务,如MNIST数据集。
下一篇
无影云桌面