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

时间:2011-01-16 15:15:53

标签: opencv

我正在开发一个应用程序,用c ++中的opencv从图像中读取字母和数字。我首先将给定的彩色图像和颜色模板更改为二进制图像,然后调用方法cvMatchTemplate()。这个方法只是突出了模板匹配的区域..但不清楚..我只是不想看到区域..我需要解析图像中的字符(字母和数字)。我是openCV的新手。有没有人知道任何其他方法来获得结果??

alt text

图像取自相机。样本图像如上所示。我需要从LED显示屏(130和Delft Tanthaf)获取所有文本。

朋友我尝试了面部检测的示例应用程序,它检测到面部。 HaarCascade文件随openCV一起提供。我刚刚加载了该文件并调用了方法cvHaarDetectObjects();要检测字母,我使用openCV提供的应用程序letter_recog.cpp创建了xml文件。但是当我加载这个文件时,它显示一些错误(OpenCV错误:UnSpecified error> in unknown function,file ........ \ ocv \ opencv \ src \ cxcore \ cxpersistence.cpp,第4720行)。我在网上搜索了这个错误,并获得了有关使用的lib文件的信息。我这样做了,但错误仍然存​​在。是我的xml文件的错误或调用方法加载此xml文件((CvHaarClassifierCascade *)cvLoad(“builded xml file name”,0,0,0);)??请帮助...

提前致谢

5 个答案:

答案 0 :(得分:16)

从OpenCV 3.0(在活动开发中),你可以使用内置的“场景文本”对象检测模块〜

文本检测基于这两篇论文:

一旦找到场景中文本的位置,就可以针对这些切片运行任何类型的标准OCR(Tesseract OCR很常见)。现在,使用OpenCV的Tesseract新界面,opencv中有一个端到端的示例:

答案 1 :(得分:9)

由于光线不一致,方向变化,尺度变化等原因,模板匹配往往不适合这种应用。解决这个问题的典型方法是引入机器学习。您通过训练自己的助推分类器尝试做的是一种可能的方法。但是,我不认为你正在进行正确的培训。你提到你给了它1个徽标作为积极的训练图像,还有5个不包含徽标的图像作为反面例子?通常,您需要训练样本大约数百或数千或更多。你不可能用6个训练样本进行训练并期望它能够发挥作用。

如果您不熟悉机器学习,那么大致您应该做什么:

1)你需要收集你想要检测的对象的许多正面训练样本(从一百个开始,但通常越多越好)。如果您尝试检测图像中的单个字符,则会获得单个字符的裁剪图像。您可以从MNIST数据库开始。更好的是,为您的特定问题训练分类器,从照片中获取许多在公交车上的角色的裁剪图像。如果您尝试检测整个矩形LED板面板,请使用它们的图像作为您的正面训练样本。

2)您需要收集许多负面训练样本。它们的数量应与您拥有的正面训练样本数量相同。这些可能是您将运行探测器的图像中出现的其他对象的图像。例如,您可以裁剪公交车前部,路面,沿路等树木的图像,并将其用作反面示例。这是为了帮助分类器排除运行探测器的图像中的这些对象。因此,负面示例不仅仅是包含您不想检测的对象的任何图像。它们应该是可能被误认为您试图在探测器上运行的图像中检测到的物体的物体(至少在您的情况下)。

请参阅以下链接,了解如何训练分类器的级联并生成XML模型文件:http://note.sonots.com/SciSoftware/haartraining.html

即使您提到您只想检测单个字符而不是总线上的整个LED面板,我建议先检测LED面板,以便本地化包含感兴趣字符的区域。之后,要么在这个较小的区域内执行模板匹配,要么运行经过训练的分类器,以识别使用滑动窗口方法获得的该区域中的像素块上的各个字符,并且可能是多尺度的。 (注意:你上面提到的haarcascade提升分类器将检测字符,但它不会告诉你它检测到哪个字符,除非你只训练它来检测那个特定字符......)以滑动窗口的方式检测这个区域中的字符会给你字符出现的顺序,这样你就可以将它们串成单词等。

希望这有帮助。

编辑:

在分别发现@KaolinFire提到的OpenCV 3中的场景文本模块之后,我偶然发现了我的这个老帖子。

对于那些好奇的人来说,这是在OP给出的样本图像上运行该检测器的结果。请注意,检测器能够本地化文本区域,即使它返回多个边界框。

Result of OpenCV 3 text detector.

请注意,此方法并非万无一失(至少在具有默认参数的OpenCV中的此实现)。它往往会产生误报,特别是当输入图像包含许多"干扰物时#34;。 以下是在Google街景数据集上使用此OpenCV 3文本检测器获得的更多示例:

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

请注意,它倾向于找到" text"平行线之间(例如,窗户,墙壁等)。由于OP的输入图像可能包含室外场景,因此这将是一个问题,特别是如果他/她不将感兴趣的区域限制在LED标志周围的较小区域。

似乎如果你能够本地化一个"粗糙的"只包含文本的区域(例如,只是OP示例图像中的LED标志),然后运行此算法可以帮助您获得更紧密的边界框。但是你必须处理假阳性(可能会丢弃小区域或使用基于知识的启发法在重叠的边界框中挑选信件出现在LED标志上)。

以下是有关文本检测的更多资源(讨论+代码+数据集)。

<强>代码

<强>数据集

您可以在此处找到google streetview和MSRA数据集。虽然这些数据集中的图像与公交车上LED标志的图像并不完全相同,但它们对于选择“最佳”和“最佳”标签可能会有所帮助。从几种竞争算法中执行算法,或从头开始训练机器学习算法。

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

答案 2 :(得分:5)

查看我对How to read time from recorded surveillance camera video?的回答您可以/应该使用cvMatchTemplate()来做到这一点。

答案 3 :(得分:1)

如果您正在使用一组固定的总线目的地,那么模板匹配就可以了。

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

答案 4 :(得分:0)

您还可以查看EAST:高效场景文本检测器-https://www.learnopencv.com/deep-learning-based-text-detection-using-opencv-c-python/ 在此链接下,您具有C ++和Python的示例。我用这段代码来检测总线的数量(在检测到给定的对象是总线之后)。