int FreeCharSet(CharSet& charSet) { for (int i = 0;i < charSet.size();i++) { cvReleaseImage(&charSet[i].image); } return charSet.size(); }
int LoadCharSet(const char* fontFileName,const char* charArray,CharSet& charSet) { if (!fontFileName || !charArray) { return 0; } IplImage* largeImage = cvLoadImage(fontFileName,CV_LOAD_IMAGE_GRAYSCALE); if (!largeImage) { return 0; } int charNum = strlen(charArray); int width = largeImage->width/charNum; int height = largeImage->height; charSet.clear(); charSet.resize(charNum); for (int i = 0;i < charNum;i++) { IplImage* image = cvCreateImage(cvSize(width,height),8,1); cvSetImageROI(largeImage,cvRect(i*width,0,width,height)); cvCopy(largeImage,image); CharFont font; font.code = charArray[i]; font.image = image; charSet[i] = font; } cvReleaseImage(&largeImage); return charSet.size(); }
MatchCharRet MatchChar(SimpleImage* image,SiRect roi,CharSet& charSet,int codeId) { MatchCharRet bestMatch = {'?'}; int XMargin = 4; int YMargin = 12; int XExtend = 0; const int SIZE = 20; SimpleImage* imgWork = siCloneImage(image); if (codeId == 3) { XExtend = 5; } // 测试所有的位置 for (int x = -XMargin; x < roi.width+XMargin+XExtend - SIZE;x++) { for (int y = -YMargin;y < roi.height+YMargin-SIZE;y++) { // 在当前位置匹配所有的字符 int x0,y0,x1,y1; // 把模板放入图像坐标系中 x0 = x + roi.x; y0 = y + roi.y; x1 = x0+SIZE; y1 = y0+SIZE; // 计算模板在图像内的范围 if (x0 < roi.x) { x0 = roi.x; } else if (x0 > roi.x + roi.width) { x0 = roi.x+roi.width; } if (y0 < roi.y) { y0 = roi.y; } else if (y0 > roi.y + roi.height) { y0 = roi.y+roi.height; } if (x1 > roi.x + roi.width) { x1 = roi.x+roi.width; } if (y1 > roi.y + roi.height) { y1 = roi.y+roi.height; } // 字体图像的有效范围 int sx = x0 - roi.x - x; int sy = y0 - roi.y - y; int ex = x1 - roi.x - x; int ey = y1 - roi.y - y; // 遍历所有的字体图像 for (int i = 0;i < charSet.size();i++) { SimpleImage* fontImage = charSet[i].image; // 匹配字体 MatchCharRet result; siCopyImage(image,imgWork); result = MatchFontImage(imgWork,x0,y0,fontImage,sx,sy,ex,ey); result.code = charSet[i].code; result.x = x+roi.x; result.y = y+roi.y; //cvShowImage("font",fontImage); //cvShowImage("match",imgWork); //cvWaitKey(); // 更新最佳匹配结果 bestMatch = UpdateBestMatchBetweenChar(bestMatch,result); } } } siReleaseImage(&imgWork); return bestMatch; }
MatchCharRet MatchChar2(SimpleImage* image,SiRect roi,CharSet& charSet,int codeId) { MatchCharRet bestMatch = {'?'}; int XMargin = 4; int YMargin = 5; int XExtend = 0; const int SIZE = 20; SimpleImage* imgWork = siCloneImage(image); if (codeId == 3) { XExtend = 5; } // 遍历所有的字体图像 for (int i = 0;i < charSet.size();i++) { SimpleImage* fontImage = charSet[i].image; MatchCharRet localeBest = {0}; // 测试所有的位置 for (int y = -YMargin;y < roi.height+YMargin-SIZE;y++) { for (int x = -XMargin; x < roi.width+XMargin+XExtend - SIZE;x++) { // 在当前位置匹配所有的字符 int x0,y0,x1,y1; // 把模板放入图像坐标系中 x0 = x + roi.x; y0 = y + roi.y; x1 = x0+SIZE; y1 = y0+SIZE; // 计算模板在图像内的范围 if (x0 < roi.x) { x0 = roi.x; } else if (x0 > roi.x + roi.width) { x0 = roi.x+roi.width; } if (y0 < roi.y) { y0 = roi.y; } else if (y0 > roi.y + roi.height) { y0 = roi.y+roi.height; } if (x1 > roi.x + roi.width) { x1 = roi.x+roi.width; } if (y1 > roi.y + roi.height) { y1 = roi.y+roi.height; } // 字体图像的有效范围 int sx = x0 - roi.x - x; int sy = y0 - roi.y - y; int ex = x1 - roi.x - x; int ey = y1 - roi.y - y; // 匹配字体 MatchCharRet result; siCopyImage(image,imgWork); result = MatchFontImage(imgWork,x0,y0,fontImage,sx,sy,ex,ey); result.code = charSet[i].code; result.x = x+roi.x; result.y = y+roi.y; // 更新最佳匹配结果 localeBest = UpdateBestMatchInChar(localeBest,result); #if DEBUG_STEP == 1 //if (codeId == 1 && (result.code == '7' || result.code == 'M')) { printf("result bb:%4d localbest bb:%4d\n",result.bb,localeBest.bb); siShowImage("font",fontImage); siShowImage("match",imgWork); cvWaitKey(); } #endif } } // 更新全局最优 bestMatch = UpdateBestMatchBetweenChar(bestMatch,localeBest); #if DEBUG_STEP == 1 printf("\nlocalbest bb:%4d best bb:%4d ch:%c\n",localeBest.bb,bestMatch.bb,bestMatch.code); #endif } siReleaseImage(&imgWork); return bestMatch; }