发布日期:2020-09-24 来源:https://blog.csdn.net/Print_lin/article/details/81052497 浏览次数:1480
Ocr文字识别其中的一大关键就是两张图片相似与否的判断,所以我们希望寻找一种或多种算法来计算图片的相似度。本文将对于项目中使用的比对算法进行介绍,并将其联合运用进行初步文字识别。
算法清单
1、像素点对比
2、重心对比
3、投影对比
4、分块对比
前提知识
计算机处理图片并不像人这样可以直观的理解处理,在计算机中的图像可以看成一个矩阵,矩阵中的元素是一个颜色值,这个值由RGB三个参数构成,这三个参数的取值范围为0~255。当然图片的表示不只有RGB这一种,其他类型不再详述。由于0~255的范围太大了,我们应该进行图片的降维——二值化。二值化将图片变成只由黑色和白色,可以使用OTSU算法。我们再将黑色用1表示,白色用0表示,这样就得到一个矩阵,矩阵中只有数字0和1组成。
(图1:二值化后的图片)
(图二:转换为01矩阵后的图片)
一、像素点对比
我们将标准图与匹配图的每个像素点进行比对,如果相等,则相似点加一。这样扫描两张完图片,我们可以得到二者之间相似点的多少,再用相似点除以总点数,就可以得到一个0~1之间的数值,这就是相似度。
(标准图)
(匹配图)
如上图所示,共100个点,只有红色点[5,1]是不一样的,所以相似度等于99/100。
这种比对算法是最简单的,但是实际应用效果不尽人意。试想,如果将匹配图的左上角多了一个点,如下图。那么将会直接导致匹配率下降很多87/100。实际中的情况远远比这复杂,所以效果欠佳。
(坏点图)
二、重心对比
有些字符除了位置不一样,二者是很相似的。如[.]与[·],所以我们需要对其进行位置的比对。可以计算其重心,判断黑色点主要是集中在什么区域。
我们循环扫描每个黑色的点,将它们的横坐标与纵坐标累加起来,得到横坐标的和与纵坐标的和。再除以点的个数,得到平均横坐标与平均纵坐标。再分别将其除以横、纵坐标的总长,得到两个个在0~1区间的数,这就代表它的重心。最后计算二者重心的距离(距离的计算将会在后文介绍),得出相似度。这种算法的缺陷也是很明显的,因为除了特殊的符号外,其他字符的重心总是相差不大的,所以精确度很低。
三、投影比对
投影比对是对行与列的黑色点个数进行统计,得到一个关于图片的特征向量,再计算二者特征向量的距离(距离的计算将在后文介绍),得出相似度。
(标准图的投影)
(匹配图的投影)
如上图所示,我们可以得到两组向量:
X:{10,102,2,10,10,2,2,10,10}Y:{8,8,6,6,6,6,6,6,8,8}
X:{10,102,2,9,10,2,2,10,10} Y:{7,8,6,6,6,6,6,6,8,8}
计算两组向量的距离,得出相似度。
这种算法将图片的特征缩小化了,比如二者第一列的统计结果都为9,我们无法知道缺的那个1的具体位置。但是将二维的匹配简化到向量距离的计算,这样更加利于计算机处理。
四、分块对比
上文中说到投影对比,它的缺陷是让图片的特征丢失过多。为了减少特征的丢失,我们可以将图片切割成几块,在分别对每一块进行匹配计算相似度,得到相似度向量,再计算向量距离,得到相似度。
分块对比不是一个具体算法,而是一种优化思路,让一张大图片的匹配变成许多小图片的匹配,这样可以使结果更为精确。
向量距离的计算
上文一直在提向量间距离的计算,可见向量间的距离是至关重要的。目前常用的算法是欧几里德距离算法。
我们可以建立标准字库(为每个字生成一张图片),将欲识别图片用以上算法到字库中进行分别匹配,得到多个相似度。我们让每个相似度乘以一个权重再先加,得出总相似度,总相似度最高的就是识别结果。这里涉及到一个问题,就是权重的确定,每个算法的平均准确度是不一样的,我们让准确度高的权重大一些。