空格识别
根据分块的左右边界坐标,比较字宽,确定是否存在空格。
首行空格:
首行空格和其余空格不同,上面和左边都没有字,只能和下一行进行比对,才能确定空格宽度,进而确定空格数目。
字中间空格:
需要完成匹配后,判断是否为标点符号,因为中文标点符号间隔较大,容易被误判成空格。
步骤:
(1) 判断是否为标点符号(其余空格)
(2) 根据间距是否大于字宽判断空格是否存在
(3) 根据间距和字宽的比值判断空格数目
代码:
首行空格:
if((leftMargin[h+1][w] - leftMargin[h][w]) < (rightMargin[h][w] - leftMargin[h][w]) && (w == 0) && (h != num_row - 1)) { ratio = (leftMargin[h][w] - leftMargin[h+1][w]) / (rightMargin[h][w] - leftMargin[h][w]); // 计算间距与字宽的比率 for(space = 0; space < 2 * ratio; space++) printf(" "); }
其他空格:
// 首先要判断是否为标点符号 if(w != 0) { if((leftMargin[h][w] - rightMargin[h][w-1]) > (rightMargin[h][w] - leftMargin[h][w])) { ratio = (leftMargin[h][w] - leftMargin[h][w-1]) / (rightMargin[h][w] - leftMargin[h][w]); // 计算间距与字宽的比率 if(ratio > 1) for(space = 0; space < ratio; space++) printf(" "); } }
模板匹配
模板匹配的核心就是在图片与图片之间的相似度的计算。
建立一个相似度指标 λ,将待识别字符图像与每个模板图像进行匹配,求得 λ_k,取得 λ_k 最小值时的对应模板字符即为所求。
f(x, y) 是指待识别字符图像中 (x,y) 点处的灰度值, f_k(x, y) 是指第k个模板图像中对应点 (x,y) 处的灰度值,k 代表字符图像模板的编号。
曼哈顿距离计算:
计算两个图片对应位置灰度值之差的绝对值。
汉明距离计算:
计算两个图片对应位置灰度值异或运算的结果。
要注意的是,由于我们预处理部分对输入的待识别图片做了反色处理,且输入图片和模板都做了二值化处理(像素值只有0和255这两种),所以反色后的输入图片和模板的灰度值不同时,两张图片相似。
代码:
imaqGetImageSize (dstImage, &width, &height); min = 100000; for(int y = 1; y < height - 1; y++) { for(int x = 1; x < width - 1; x++) { point1.x = x; point1.y = y; imaqGetPixel(dstImage, point1, &pix1); cmp[x][y] = pix1.grayscale; // 记录待匹配文字灰度值 } } for(int i = 0; i < num_word; i++) { score = 0; imaqGetImageSize (fontsImage[i], &width, &height); for(int y = 1; y < height - 1; y++) { for(int x = 1; x < width - 1; x++) { point2.x = x; point2.y = y; imaqGetPixel(fontsImage[i], point2, &pix2); // similarity = abs(cmp[x][y] - pix2.grayscale); // 曼哈顿距离 similarity = cmp[x][y] ^ (int)pix2.grayscale; // 汉明距离 if(similarity == 0) score++; } } if(score < min) { min = score; label = i; // 记录匹配对象 } }
最终效果
输入图片:
行列分割效果图:
匹配效果:
控制台输出: