使用OpenCV从图像中读取数字和字母

23

我正在开发一个使用OpenCV在C++中从图像中读取字母和数字的应用程序。我首先将给定的彩色图像和彩色模板转换为二进制图像,然后调用了cvMatchTemplate()方法。这个方法只是突出显示模板匹配的区域.. 但不清晰.. 我只是不想看到这个区域.. 我需要从图像中解析字符(字母和数字)。我对OpenCV还很陌生。有人知道其他获取结果的方法吗?

alt text

图片来自相机。示例图像如上所示。我需要从LED显示器(130和Delft Tanthaf)中获取所有文本。

朋友们,我尝试了面部检测的示例应用程序,它可以检测到人脸。HaarCascade文件已经提供了openCV。我只需加载该文件并调用方法cvHaarDetectObjects()即可。为了检测字母,我使用openCV提供的应用程序letter_recog.cpp创建了xml文件。但是当我加载此文件时,它会显示一些错误(OpenCV错误:未指定错误>在未知函数中,文件........\ ocv \ opencv \ src \ cxcore \ cxpersistence.cpp,第4720行)。我在网上搜索了这个错误,并获得了有关使用的lib文件的信息。我这样做了,但错误仍然存在。是我的xml文件出错还是调用方法以加载此xml文件((CvHaarClassifierCascade*)cvLoad("builded xml file name",0,0,0);)?请帮忙......

提前感谢

5个回答

17
截至OpenCV 3.0(处于活跃开发阶段),您可以使用内置的“场景文本”对象检测模块 ~。
参考:http://docs.opencv.org/3.0-beta/modules/text/doc/erfilter.html 示例:https://github.com/Itseez/opencv_contrib/blob/master/modules/text/samples/textdetection.cpp 文本检测基于以下两篇论文:
[Neumann12] Neumann L., Matas J.: Real-Time Scene Text Localization and Recognition, CVPR 2012。该论文可在线获取:http://cmp.felk.cvut.cz/~neumalu1/neumann-cvpr2012.pdf
[Gomez13] Gomez L. and Karatzas D.: Multi-script Text Extraction from Natural Scenes, ICDAR 2013。该论文可在线获取:http://refbase.cvc.uab.es/files/GoK2013.pdf
一旦您找到场景中的文本所在位置,就可以对这些片段运行任何标准OCR(Tesseract OCR很常见)。现在,OpenCV使用其新接口与Tesseract的端到端示例: https://github.com/Itseez/opencv_contrib/blob/master/modules/text/samples/end_to_end_recognition.cpp

没有提供参考或示例。 - Dmitry Zaytsev
2
嗯,奇怪他们把它全部移动了。:/ 我会尽力更新。 - Kaolin Fire

11
Template matching在这种应用中往往不够稳健,因为存在光照不一致、方向变化、尺度变化等问题。解决这个问题的典型方法是引入机器学习。通过训练自己的增强分类器来实现你正在尝试的目标是一种可能的方法。然而,我认为你没有正确地进行训练。你提到给了它1个带有正标志的训练图像和5个不包含标志的负样本?通常情况下,你需要的训练样本数量应该是数百或数千甚至更多。你不可能只用6个训练样本来进行训练并期望它能工作。
如果你对机器学习不熟悉,以下是你应该做的大致步骤:
1)你需要收集许多正样本(从几百个开始,但通常越多越好)以便训练检测对象。如果你想检测图像中的单个字符,则需获取单个字符的裁剪图像。你可以从MNIST数据库开始。更好的方法是,为了针对你特定的问题训练分类器,请从照片中获得公交车上的许多字符的裁剪图像。如果你想检测整个长方形LED面板,则使用它们的图像作为你的正样本。
2) 您需要收集许多负面训练样本。它们的数量应与您拥有的正面训练样本相同。这些可以是出现在您检测器运行的图像中的其他对象的图像。例如,您可以裁剪公共汽车前部、路面、路边树木等图像,并将其用作负面示例。这有助于分类器在您运行检测器的图像中排除这些对象。因此,负面示例不仅仅是包含您不想检测的对象的任何图像。它们应该是在您运行检测器的图像中可能被误认为是您要检测的对象的对象(至少对于您的情况而言)。
请参见以下链接,了解如何训练级联分类器并生成XML模型文件:http://note.sonots.com/SciSoftware/haartraining.html 尽管您提到您只想检测公交车上的单个字符而非整个LED面板,但我建议先检测LED面板以定位包含所需字符的区域。之后,可以在该较小区域内执行模板匹配,或者使用滑动窗口方法获取该区域中像素块上训练过识别单个字符的分类器,并可能在多个比例下运行。 (注意:您上面提到的haarcascade boosting分类器将检测字符,但除非您仅训练它以检测特定字符,否则它不会告诉您检测到了哪个字符...)以滑动窗口方式在此区域中检测字符将给您字符出现的顺序,因此您可以将它们组合成单词等等。
希望这能有所帮助。
编辑:
我刚好在另外发现了OpenCV 3中提到的场景文本模块,并在单独的帖子中看到了我的旧帖子。
对于那些感兴趣的人,这是在OP给出的示例图像上运行该检测器的结果。请注意,该检测器能够定位文本区域,即使它返回了多个边界框。

Result of OpenCV 3 text detector.

请注意,这种方法并非百分之百可靠(至少在OpenCV默认参数下的实现)。它倾向于产生错误的正面反应,特别是当输入图像包含许多“干扰因素”时。以下是在Google Street View数据集上使用此OpenCV 3文本检测器获取的更多示例:

Negative result 1 Negative result 2 Negative result 3 Negative result 4

请注意,它有一个倾向于在平行线之间(例如窗户、墙壁等)找到“文本”的趋势。由于OP的输入图像可能包含室外场景,如果他/她不将感兴趣的区域限制在LED标志周围的较小区域内,则这将是一个问题。
看起来,如果您能够定位包含文本的“粗略”区域(例如OP样本图像中的LED标志),那么运行此算法可以帮助您获得更紧密的边界框。但是您将不得不处理假阳性(也许舍弃小区域或使用基于关于字母出现方式的知识的启发式方法在重叠的边界框之间选择)。
以下是有关文本检测的更多资源(讨论+代码+数据集)。 代码

数据集

您可以在此处找到Google Streetview和MSRA数据集。尽管这些数据集中的图像与公交车上LED标志的图像不完全相同,但它们可能有助于从多个竞争算法中选择“最佳”性能算法,或从头开始训练机器学习算法。

http://www.iapr-tc11.org/mediawiki/index.php/Datasets_List


6

但是图像中数字的位置可能会有所不同,因此无法比较特定位置的图像。如果要比较的图像不清晰,那么我该如何从图像中获取特定的数字呢? - asifkt
@asifkt,请编辑您的问题,提供更多关于您的应用程序的详细信息。您了解有关字母(字体、大小、透视)和图像来源(视频、扫描仪等)的更多信息吗?这将有助于集中关注可能的解决方案。 - Adi Shavit
我开发了一个人脸检测应用程序。实际上,opencv提供了级联文件haarcascade_frontalface_alt.xml。为了进行字母识别,我需要创建一个xml文件。因此,我使用了opencv_createsamples.exe、opencv_haartraining.exe文件来创建这个文件。我将一个标志作为正面图像,并将另外5个不包含标志的图像作为负面图像。但是训练后我没有得到任何xml文件。听说haar训练至少需要3天时间。这是真的吗?为了获得中间的xml文件,我需要使用convert_cascade.exe文件。如果我使用它,会得到更好的结果吗? - asifkt

1

如果您正在使用固定的巴士目的地集合,那么模板匹配就可以了。

但是,如果您希望系统更加灵活,我想您需要对每个单独的字母进行某种形状分析/轮廓分析。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接