基于KNN的手写体识别和数码管数字识别

大神符识别主要有数码管数字和手写体数字两种
数码管:
1.先进行整副图像的

处理,可以看出数码管红色很明显,所以可以进行图像通道分离,然后对红色通道二值化

基于KNN的手写体识别和数码管数字识别

效果: 
基于KNN的手写体识别和数码管数字识别

2.进行轮廓提取(findcontours),通过大小形状来滤除小的杂讯
3.由于大神符的打击需要顺序,所以要对提取的轮廓进行排序,排序的方法是通过x坐标的大小
4.利用穿线法进行提取后的数码管字体的识别,所谓穿线法就是在提取的字体的(height/3),(2*height/3),(width/2)位置处画3条线,然后数交点个数和位置进行分类。

我用的是提取出那三条线位置处的行列矩阵,函数是Mat.rowRange(x,x+1) 

基于KNN的手写体识别和数码管数字识别

判断的效果 

基于KNN的手写体识别和数码管数字识别


手写字体:
1.手写体的预处理和数码管差不多,进行二值化,膨胀腐蚀,轮廓提取
2.识别方法用的是knn方法,knn是通过对大量测试数据分类,比如0-9这10种数字各50张分类为10份,贴上标签0-10,用knn.train(trainData,trainClasses,Mat(), false, K );进行训练,其中的traindata是训练样本矩阵(N*M)N为样本数,及矩阵行数,M是单个样本的特征值,这里的特征值是把单个字符的像素值用Mat row2=ROI.reshape(0,1);//把矩阵转至成行得到的,trainclass是一个标签矩阵每一个标签一行,traindata的目的是进行监督学习,告诉机器哪类特征对应哪类标签,然后就可以通过knn.findneast来通过样本的特征对应相应的标签
然后在检测的时候用float result=knn.find_nearest(row2,K);来进行矩阵临近值的分类,比如我识别到row2这个矩阵有K个临近值(k是参数自己设的,K越大精度越高但是速度越慢)(识别临近值是通过匹配归一化后的矩阵的像素点得到的ROI.convertTo(ROI,CV_32FC1,0.0039215);//把【0-255】进行矩阵归一化到【0-1】
Mat row2=ROI.reshape(0,1);//把矩阵转至成行
),然后对标签进行投票,比如有5个临近值K,3票1,1票2,一票3,那么就分类为票数最多的1


3.最后就是对数码管数字和手写体数字的匹配了(这个不难)


最后发现knn的识别率与样本数量(越大越精确),K值大小(越大越精确),但是速度会越慢,KNN比较鸡肋,识别率在90%吧大概,但是对于9个数字的大神符大概有一半的图片有一个手写体数字识别不了8个没问题,一半图片完全正确

最终匹配效果

基于KNN的手写体识别和数码管数字识别

代码链接:https://download.****.net/download/qq_35971623/10290937