37

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

提取车牌

提取车牌

但正如您所见,OCR 结果非常糟糕。

tesseract在我的Objective C(iOS)环境中使用。这些是我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改进的吗?

4

5 回答 5

57

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

  1. 从图像中删除所有不是文本的内容。您需要使用一些 CV 来查找印版区域(例如通过颜色等),然后遮盖所有背景。您希望 tesseract 的输入是黑白的,其中文本是黑色的,其他一切都是白色的

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

一些进一步的指示...

首先不要尝试对此进行编码:拍摄一张非常容易 OCR(即:直接从正面,无透视)的盘子图片,在 Photoshop(或 gimp)中对其进行编辑,然后在命令行上通过 tesseract 运行它。继续以不同的方式进行编辑,直到这有效。例如:按颜色选择(或泛洪选择字母形状),用黑色填充,反转选择,用白色填充,透视变换使板的角变成矩形等。拍一堆照片,一些更难的(可能是奇数)角度等)。对所有人都这样做。一旦这完全起作用,请考虑如何制作一个与您在 photoshop 中做的事情相同的 CV 算法 :)

PS 另外,如果可能的话,最好从更高分辨率的图像开始。看起来您示例中的文本大约 14 像素高。tesseract 适用于 300 dpi 的 12 点文本,大约 50 像素高,在 600 dpi 时效果更好。尝试使您的字母大小至少为 50,最好是 100 像素。

PPS 你在做任何事情来训练 tesseract吗?我认为你必须这样做,这里的字体不同,足以成为一个问题。您可能还需要一些东西来识别(而不是惩罚)在您的文本中非常常见的破折号,就像在第二个示例中“T-”被识别为 H.

于 2013-10-17T04:31:01.910 回答
13

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

  • 在 OCR 任务中,您需要确保您的训练数据具有您尝试识别的相同字体。或者,如果您尝试识别多种字体,请确保您的训练数据中包含这些字体以获得最佳性能。
  • 据我所知,tesseract 以几种不同的方式应用 OCR:第一,您提供一张包含多个字母的图像,然后让 tesseract 进行分割。其他的,你给 tesseract 提供分段的字母,只期望它识别字母。也许您可以尝试更改您正在使用的那个。
  • 如果您自己训练识别器,请确保您的训练数据中每个字母的数量足够且数量相等。

希望这可以帮助。

于 2013-10-09T12:08:09.860 回答
9

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

所以,我过去使用这个要点来训练带有车牌字体的 tesseract ORC。

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

于 2013-10-22T18:40:46.223 回答
2

这是我从旧功率计中尝试 OCR 的真实示例。我想使用您的 OpenCV 代码,以便 OpenCV 自动裁剪图像,我将执行图像清理脚本。

  • 第一个图像是原始图像(裁剪的功率计编号)
  • 第二张图像在 GIMP 中经过轻微清理,在 tesseract 中的 OCR 准确率约为 50%
  • 第三张图像是完全清洁的图像 - 100% OCR 识别,无需任何培训!

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

于 2013-11-05T11:34:22.827 回答
2

现在车牌可以很容易地被 mlmodel 识别。我已经创建了核心模型,您可以在此处找到它。您只需要通过视觉框架以 28*28 分辨率拆分字符并将此图像发送到 VNImageRequestHandler,如下所示 -

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

通过使用我的核心 mlmodel,您将获得所需的结果。使用链接以获得更好的说明,但使用我的模型以获得更好的车牌识别结果。我还为车牌识别创建了mlmodel 。

于 2017-11-21T13:58:23.833 回答