我正在编写一个OCR应用程序来读取截图图像中的字符。目前,我只关注数字。我部分基于这篇博客文章的基础:http://blog.damiles.com/2008/11/basic-ocr-in-opencv/。
我可以使用一些聪明的阈值来成功提取每个角色。事情变得有点棘手的是匹配角色。即使使用固定的字体和大小,也有一些变量,如背景颜色和字距调整,导致相同的数字以略微不同的形状出现。例如,下面的图像被分为3个部分:
部件全部缩放(两条绿色水平线之间的距离代表一个像素)。
你可以看到,尽管顶部和中间的图像清晰地表示为2,但它们之间的误差非常高。当匹配其他数字时,这会导致误报 - 例如,不难看出位置优良的7如何能够匹配上图中的目标数字,而不是中间图像。
目前,我正在处理这个问题,方法是为每个数字提供一堆训练图像,并将目标数字与这些图像匹配,逐个。我尝试拍摄训练集的平均图像,但这并不能解决问题(其他数字的误报)。
我有点不愿意使用移位模板进行匹配(它与我现在正在做的基本相同)。比较简单的绝对差异是否有更好的方法来比较两个图像?我想的可能是2D中的EMD(地球移动距离,http://en.wikipedia.org/wiki/Earth_mover's_distance):基本上,我需要一种对全局移位和小局部变化不敏感的比较方法(旁边的像素)白色像素变为白色,或黑色像素旁边的像素变为黑色,但对全局变化敏感(白色像素附近的黑色像素变为黑色,反之亦然)。
有人建议比绝对差异更有效的匹配方法吗?
我正在使用C风格的Python包装器(import cv
)在OpenCV中完成所有这些。
答案 0 :(得分:6)
我会考虑使用Haar级联。我已经将它们用于人脸检测/头部跟踪,看起来你可以建立一套相当不错的级联,包括足够的 2' 3, ' 4'等等。
答案 1 :(得分:3)
嘈杂图像上的OCR并不容易 - 如此简单的方法并不能很好地工作。
因此,我建议您使用HOG提取要素和SVM进行分类。 HOG似乎是描述形状的最有效方法之一。
整个处理管道在OpenCV中实现,但我不知道python包装器中的函数名称。你应该能够使用最新的haartraining.cpp进行训练 - 它实际上支持的不仅仅是haar - HOG和LBP。
我认为最新的代码(来自主干)比官方版本(2.3.1)有了很大改进。
HOG通常只需要其他识别方法使用的训练数据的一小部分,但是,如果要对部分被遮挡(或缺失)的形状进行分类,则应确保在训练中包含一些此类形状。
答案 2 :(得分:3)
我可以从我的经验和阅读有关角色分类的几篇论文中告诉你,一个好的开始方式是阅读主成分分析(PCA),Fisher线性判别分析(LDA)和支持向量机(SVMs) )。这些是对OCR非常有用的分类方法,事实证明OpenCV已经在PCAs和SVMs上包含了出色的实现。我还没有看到任何针对OCR的OpenCV代码示例,但您可以使用某些修改版的面部分类来执行字符分类。 OpenCV的面部识别代码的优秀资源是this website。
我推荐你的另一个Python库是“scikits.learn”。将cvArrays发送到scikits.learn并在数据上运行机器学习算法非常容易。使用SVM的OCR的基本示例是here。
使用流形学习进行手写字符识别的另一个更复杂的例子是here。