我正在开发一款可识别车牌(ANPR)的应用程序。第一步是从图像中提取牌照。我正在使用OpenCV来检测基于宽高比的印版,这非常有效:
但正如您所看到的,OCR结果非常糟糕。
我在tesseract
(iOS)环境中使用Objective C
。这些是启动引擎时的init
变量:
// init the tesseract engine.
tesseract = new tesseract::TessBaseAPI();
int initRet=tesseract->Init([dataPath cStringUsingEncoding:NSUTF8StringEncoding], [language UTF8String]);
tesseract->SetVariable("tessedit_char_whitelist", "BCDFGHJKLMNPQRSTVWXYZ0123456789-");
tesseract->SetVariable("language_model_penalty_non_freq_dict_word", "1");
tesseract->SetVariable("language_model_penalty_non_dict_word ", "1");
tesseract->SetVariable("load_system_dawg", "0");
如何改善结果?我是否需要让OpenCV进行更多的图像处理?或者有什么我可以通过tesseract改进吗?
答案 0 :(得分:48)
有两件事情可以解决这个问题:
从图片中删除 not text 的所有内容。您需要使用一些CV来查找印版区域(例如通过颜色等),然后屏蔽背景的所有。您希望tesseract的输入为黑色和白色,其中文本为黑色,其他所有内容为白色
删除偏斜(如上面的FrankPI所述)。 tesseract实际上应该适用于偏斜(参见R. Smith的“Tesseract OCR Engine”概述)但另一方面它doesn't always work,特别是如果你有一行而不是几段。因此,如果您可以可靠地执行此操作,首先手动删除倾斜总是好的。你可能会知道步骤1中板块的边界梯形的确切形状,所以这不应该太难。在删除歪斜的过程中,您还可以删除透视:所有牌照(通常)都具有相同的字体,如果您将它们缩放到相同(无透视)的形状,字母形状将完全相同,这将有助于文本识别。
一些进一步的指示......
首先不要尝试对此进行编码:从一个非常容易的OCR(即:直接从前面,没有透视)图片的板块,在photoshop(或gimp)中编辑它并通过tesseract运行它命令行。以不同的方式继续编辑,直到这样做。例如:按颜色选择(或选择字母形状的洪水),填充黑色,反转选择,填充白色,透视变换,因此板的角是矩形等。拍摄一堆图片,一些更难(可能来自奇数角度等)。与所有人一起做这件事。一旦完成,请考虑如何制作一个与你在photoshop中做同样事情的CV算法。
P.S。此外,如果可能,最好从更高分辨率的图像开始。看起来您的示例中的文本大约14像素高。 tesseract与300 dpi的12点文本相当不错,大约50像素高,在600 dpi时效果更好。尽量让你的信件大小至少为50,最好是100像素。
P.P.S。你在为train tesseract做些什么吗?我认为你必须这样做,这里的字体不同就足以成为一个问题。您可能还需要识别(而不是惩罚)破折号,这些破折号在您的文本中非常常见,在第二个示例中看起来“T-”被识别为H.
答案 1 :(得分:13)
我不太了解tesseract,但我有一些关于OCR的信息。我们走了。
希望这有帮助。
答案 2 :(得分:8)
我一直在研究iOS应用程序,如果你需要改进你应该训练tesseract OCR的结果,这对我来说提高了90%。在转换之前,OCR结果非常糟糕。
所以,我过去使用这个gist用牌照字体训练tesseract ORC。
如果您有兴趣,我几周前在github
上开源了这个项目答案 3 :(得分:2)
这是我从旧功率计中尝试OCR的真实世界示例。我想使用你的OpenCV代码,以便OpenCV自动裁剪图像,我会做图像清理脚本。
答案 4 :(得分:1)