使用tesseract识别牌照

我正在开发一个可以识别车牌(ANPR)的应用程序。 第一步是从图像中提取牌照。 我使用OpenCV来检测基于宽度/高度比的板,这个工作非常好:

提取车牌

提取车牌

但是,正如你所看到的,OCR结果非常糟糕。

我在Objective C (iOS)环境中使用tesseract 。 这些是我启动引擎时的initvariables:

 // 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做更多的image processing吗? 还是有什么我可以改善tesseract?

有两件事将完全解决这个问题:

  1. 从图像中删除所有不是文本的内容。 你需要使用一些简历find版面区域(例如,通过颜色等),然后掩盖所有的背景。 你想inputtesseract是黑色和白色,其中文字是黑色的,其他一切都是白色的

  2. 消除歪斜(如上面FrankPI所述)。 实际上,tesseract实际上应该可以与倾斜一起工作(请参阅R. Smith的“ Tesseract OCR Engine ”概述),但是另一方面,它并不总是有效 ,特别是如果您有一行而不是几段。 所以,如果你能够可靠地做到这一点,那么首先手动去除歪斜总是很好的。 你可能会从步骤1知道板的边界梯形的确切形状,所以这不应该太难。 在消除歪斜的过程中,您也可以删除透视图:所有牌照(通常)都具有相同的字体,如果将它们缩放到相同(无透视)的形状,字母形状将完全相同,这将有助于文字识别。

一些进一步的指针…

首先不要尝试编写这个代码:在OCR(例如:直接从前面看,没有透视图)的图片上进行编辑,在photoshop(或gimp)中进行编辑,然后通过命令行上的tesseract运行。 以不同的方式继续编辑,直到这个工作。 例如:按颜色select(或泛光select字母形状),用黑色填充,反转select,用白色填充,透视变换,使得板的angular是矩形等等。拍一堆照片,一些更难(可能来自奇数angular度等)。 用所有这些来做到这一点。 一旦这完全工作,想想如何做一个简历algorithm,做同样的事情,你在Photoshop中:)

PS另外,如果可能的话,最好从更高分辨率的图像开始。 它看起来像在你的例子中的文字高约14像素。 在300 dpi的分辨率下,tesseract工作得非常好,大约有50个像素点,在600 dpi的分辨率下效果更好。 试着让你的字母大小至less50个,最好是100个像素。

PPS你在做什么来训练tesseract ? 我认为你必须这样做,这里的字体是不一样的,是一个问题。 你可能也需要一些东西来识别(而不是惩罚)在你的文本中很常见的破折号,看起来像在第二个例子中,“T-”被识别为H.

我不太了解tesseract,但我有一些关于OCR的信息。 开始了。

  • 在OCR任务中,您需要确保您的列车数据具有您想要识别的相同字体。 或者,如果您尝试识别多种字体,请确保您的列车数据中包含这些字体以获得最佳性能。
  • 据我所知,tesseract以几种不同的方式应用OCR:一是给一个有多个字母的图像,让tesseract做分割。 而其他的,你给分段的信件tesseract,只希望它认出这封信。 也许你可以尝试改变你正在使用的那个。
  • 如果您自己正在训练识别器,请确保您的火车数据中的每个字母都有足够的数量。

希望这可以帮助。

我一直在iOS应用程序上工作,如果你需要改进结果,你应该训练tesseract OCR,这对我来说提高了90%。 在转换之前,OCR结果非常糟糕。

所以,我以前用这个要点来训练tesseract ORC牌照字体。

如果你有兴趣,我几周前在github上公开了这个项目

这是我现实世界的例子,从我的旧功率表中尝试OCR。 我想使用你的OpenCV代码,以便OpenCV自动裁剪图像,我会做图像清理脚本。

  • 第一张图片是原始图片(歪斜的功率计数字)
  • 第二张图像在GIMP中略微清理图像,在图像中约有50%的OCR精度
  • 第三个图像是完全清洁的图像 – 100%的OCR认可没有任何培训!

在这里输入图像说明在这里输入图像说明在这里输入图像说明

现在可以通过mlmodel轻松识别车牌。 我已经创build了核心模型,你可以在这里find它。 您只需要通过视觉框架以28 * 28分辨率分割字符,并将此图像发送到VNImageRequestHandler(如下所示)

 let handler = VNImageRequestHandler(cgImage: imageUI.cgImage!, options: [:]) 

你将通过使用我的核心mlmodel得到期望的结果。 使用此链接更好的澄清,但使用我的模型更好的车牌识别结果。