基于opencv的手写数字字符识别
基于OpenCV的手写数字
字符识别
2013级 计算机软件不理论
摘要
本程序主要参照
,《基于OpenCV的脱机手写字符识别技术》实现了,对于手写阿拉伯数字的识别工作。识别工作分为三大步骤:预处理,特征提取,分类识别。预处理过程主要找到图像的ROI部分子图像并进行大小的归一化处理,特征提取将图像转化为特征向量,分类识别采用k-近邻分类方法进行分类处理,最后根据分类结果完成识别工作。
程序采用Microsoft Visual Studio 2010不OpenCV2.4.4在Windows 7-64位旗舰版系统下开发完成。并在Windows xp-32位系统下测试可用。 主流程图:
预处理(图片大小归一化)
特征提取
分类识别
细化流程图:
测试图片训练样本用户手写Pbm格式Pbm格式输入的数字图片
预处理
找到ROI(Region of Interest )区域
测试数据训练数据用户数据
Knn近邻训练
Knn::train()
测试数据knn近邻分类法,分类分类正确Knn::find_nearest()率
分类识别
结果
1. 预处理
预处理的过程就是找到图像的ROI区域的过程,如下图所示:
首先找到数字的边界框,然后大小归一化数字图片,主要流程如下图所示:
主要代码:
IplImage preprocessing(IplImage* imgSrc,int new_width, int new_height) {
IplImage* result;
IplImage* scaledResult;
CvMat data;
CvMat dataA;
CvRect bb;//bounding box
CvRect bba;//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);
//将图像放中间,大小归一化
size-bb.width)/2.0f); int x=(int)floor((float)(
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图像减少了信息量之后,就可以直接用图片作为向量矩阵作为输
入:
void basicOCR::getData()
{
IplImage* src_image;
IplImage prs_image;
CvMat row,data;
char file[255];
int i,j;
for(i =0; i
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. 提高识别速度,改进算法为并行算法,实现如联机在线识别等。