2012-01-02 43 views
8

我正在编写OCR应用程序以从屏幕截图图像中读取字符。目前,我只关注数字。我部分基于我的方法在这篇博文中:http://blog.damiles.com/2008/11/basic-ocr-in-opencv/来自屏幕截图的低分辨率文本的OCR

我可以使用一些聪明的阈值成功地提取每个单独的字符。有些棘手的地方是匹配字符。即使使用固定的字体和大小,也会有一些变量,例如背景颜色和字距,这些变量会导致相同的数字以不同的形状出现。例如,下面的图像分割成3个部分:

  1. 上:我成功地从截图中提取的对象位的
  2. 中东:模板:从我训练的一个数字设置
  3. 下图:顶部和中间图像之间的误差(绝对差值)

零件已全部缩放(两条绿色水平线之间的距离表示一个像素)。

topbottommiddle

你可以看到,尽管顶部和中间图像清晰表示2,它们之间的误差是相当高的。这会导致在匹配其他数字时出现误报 - 例如,不难看出放置良好的7可以如何匹配图像中的目标数字比中间图像更好。

目前,我正在处理这个问题的方法是为每个数字设置一堆训练图像,并将目标数字与这些图像相匹配,一一对应。我尝试了训练集的平均图像,但这并不能解决问题(其他数字上的误报)。

我有点不愿意使用移位模板执行匹配(它与我现在所做的基本相同)。有没有比简单的绝对差异更好地比较两幅图像的方法?我想到的可能是类似于2D中的EMD(推土机距离,http://en.wikipedia.org/wiki/Earth_mover's_distance):基本上,我需要一种比较方法,它不像全局移动和局部小变化那样敏感(白色像素旁边的像素变为白色,或黑色像素旁边的像素变为黑色),但对全局变化敏感(黑色像素远不及白色像素变为黑色,反之亦然)。

任何人都可以提出一个比绝对差异更有效的匹配方法吗?

我使用C风格的Python包装(import cv)在OpenCV中完成所有这些工作。

回答

6

我会考虑使用哈尔瀑布。我用它们进行人脸检测/头部追踪,似乎你可以用足够的'2','3','4'等来建立一个相当不错的级联。

http://alereimondo.no-ip.org/OpenCV/34

http://en.wikipedia.org/wiki/Haar-like_features

+0

谢谢!我一定会看看哈尔瀑布。你认为它将与简单图像减法相比有多高效?我预计它会变慢。但是,如果速度慢5倍,但取代10个图像检查以获得相同的效果,那么它肯定值得。 – misha 2012-01-02 05:03:38

+0

您必须生成级联,这是一个非常耗时的过程(但也是愚蠢的可并行化)。它还需要大量的输入数据(我会使用桌面上每种字体的数字)。 – rsaxvc 2012-01-02 05:17:04

+0

慢于减法,但您可以一次搜索特定级联的所有实例的图像。 – rsaxvc 2012-01-02 05:19:19

3

OCR在嘈杂的图像是不容易的 - 这么简单的方法没有效果不佳。

因此,我建议您使用HOG来提取要分类的特征和SVM。 HOG似乎是描述形状最有力的方法之一。

整个处理管道在OpenCV中实现,但我不知道python包装中的函数名称。你应该可以用最新的haartraining.cpp进行训练 - 它实际上支持的不仅仅是haar - 还有HOG和LBP。

我认为最新的代码(来自主干)比官方发布(2.3.1)有了很大的改进。

HOG通常只需要其他识别方法使用的训练数据的一小部分,但是,如果要对部分被遮挡(或缺失)的形状进行分类,则应确保在训练中包含一些这样的形状。

+0

我不会把图像*吵杂*本身,但我看到你来自哪里。我会看看HOG。谢谢。 – misha 2012-01-02 07:53:47

3

我可以从我的经验和阅读关于字符分类的几篇论文告诉你,一个好的开始方法是阅读主成分分析(PCA),Fisher线性判别分析(LDA)和支持向量机(支持向量机)。这些是对OCR非常有用的分类方法,事实证明OpenCV已经在PCAsSVMs中包含了出色的实现。我还没有看到任何OCR的OpenCV代码示例,但是您可以使用一些修改后的脸部分类版本来执行字符分类。 OpenCV的面部识别代码的优秀资源是this website

我推荐你的另一个Python库是“scikits.learn”。将cvArrays发送到scikits非常容易。在数据上学习和运行机器学习算法。使用SVM的OCR的基本示例是here

使用流形学习进行手写字符识别的另一个更复杂的示例是here