我想通过简单的模板匹配来进行图像识别。
把预处理好的字符图片,分别与A到J的样本图片进行模板匹配。结果最大的表明相关性最大,就可以识别字符图片了。
在实际应用中,我用了openCV的matchTemplate()函数,但是未达到我想要点的效果。
matchTemplate()的功能是在图像中搜索出指定的模板,如果模板是从待搜索的图像中截取出来的,会有很好的效果。但是如果模板不是待搜素图像的一部分,似乎达不到我想要的效果。
在尝试了matlab的corr2()后,发现corr2能很好的解决我的问题。
double Card::corr2(Mat matA, Mat matB){ //计算两个相同大小矩阵的二维相关系数 double corr2 = 0; double Amean2 = 0; double Bmean2 = 0; for (int m = 0; m < matA.rows; m++) { uchar* dataA = matA.ptr<uchar>(m); uchar* dataB = matB.ptr<uchar>(m); for (int n = 0; n < matA.cols;n++) { Amean2 = Amean2 + dataA[n]; Bmean2 = Bmean2 + dataB[n]; } } Amean2 = Amean2 / (matA.rows * matA.cols); Bmean2 = Bmean2 / (matB.rows * matB.cols); double Cov = 0; double Astd = 0; double Bstd = 0; for (int m = 0; m < matA.rows; m++) { uchar* dataA = matA.ptr<uchar>(m); uchar* dataB = matB.ptr<uchar>(m); for (int n = 0; n < matA.cols;n++) { //协方差 Cov = Cov + (dataA[n] - Amean2) * (dataB[n] - Bmean2); //A的方差 Astd = Astd + (dataA[n] - Amean2) * (dataA[n] - Amean2); //B的方差 Bstd = Bstd + (dataB[n] - Bmean2) * (dataB[n] - Bmean2); } } corr2 = Cov / (sqrt(Astd * Bstd)); return corr2; }
//待搜索图像 Mat srcImage = imread("M:/图像处理实验/验证码/byx001.bmp",1); Mat resizeMat = Mat::zeros(25, 25, CV_8UC3); //缩放为25*25的矩阵。因为要相关匹配的模板大小为25*25 resize(srcImage,resizeMat,resizeMat.size()); //相关匹配 double ccorrVal[26] = {0}; double max = 0; int count = 0; for (int m = 0; m < 26; m++){ char recogPath[100] = {1}; strcpy(recogPath,"M://图像处理实验//验证码//大写字母//"); char num[2] = {1}; num[0] = 65 + m; strcat(recogPath, num); strcat(recogPath,".bmp"); Mat img_display; resizeMat.copyTo( img_display ); Mat std = imread(recogPath,0); Mat resizeMatSTD = Mat::zeros(25, 25, CV_8UC3); resize(std,resizeMatSTD,resizeMatSTD.size()); adaptiveThreshold(resizeMatSTD ,resizeMatSTD ,255 ,ADAPTIVE_THRESH_MEAN_C ,THRESH_BINARY,5,1); corr2Val[m] = corr2(resizeMatSTD,img_display); if (max <= corr2Val[m]){ max = corr2Val[m]; count = m; } } char pathname[100]={1}; strcpy(pathname,"M://图像处理实验//验证码//test//字符_"); char num[10]; _itoa(i, num, 10); strcat(pathname, num); char C[2] = {1}; C[0] = 65 + count; strcat(pathname, C); strcat(pathname,".bmp"); imwrite(pathname, resizeMat);
字符模板:
识别结果输出: