扫描名片 Tesseract 和 Leptonica iOS

Posted

技术标签:

【中文标题】扫描名片 Tesseract 和 Leptonica iOS【英文标题】:Scan Business Card Tesseract and Leptonica iOS 【发布时间】:2014-02-24 13:21:48 【问题描述】:

我正在尝试使用 tesseract OCR 扫描名片,我所做的只是发送图像而不进行预处理,这是我正在使用的代码。

 Tesseract* tesseract = [[Tesseract alloc] initWithLanguage:@"eng+ita"];
tesseract.delegate = self;
[tesseract setVariableValue:@"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@.-()" forKey:@"tessedit_char_whitelist"];

[tesseract setImage:[UIImage imageNamed:@"card.jpg"]]; //image to check
[tesseract recognize];

 NSLog(@"Here is the text %@", [tesseract recognizedText]);

Picture of card

This is the output

如您所见,准确度不是 100%,这不是我关心的问题,我想我可以通过一些简单的每次处理来解决这个问题。但是,如果您注意到它混合了底部的两个文本块,从而将地址和其他卡片上的其他信息分开。

我怎么可能使用 Leptonica(或其他可能的 OpenCV)以某种方式对文本进行分组?可能将图像上的文本区域单独发送到 tesseract 进行扫描? 我已经被这个问题困扰了一段时间,欢迎任何可能的解决方案!

【问题讨论】:

【参考方案1】:

我建议使用一种称为“游程平滑算法”(RLSA) 的算法。该算法在许多文档图像处理系统中都有使用,但并非每个系统都将其作为其 API 的一部分公开。

original paper 发布于 1982 年,需要付费。但是,许多其他有关文档图像处理的论文都引用了相同的算法,您可以在其中轻松找到实现细节和改进。

这样的论文是这样的:http://www.sciencedirect.com/science/article/pii/S0262885609002005

基本思路是逐行扫描文档图像,记录字母之间的间隙宽度。

然后,可以通过对间隙的宽度进行过滤并将小间隙设置为与文本相同的颜色来组合附近的文本字符。结果将是大型连接组件,它们表示:

的话, 通过缩小字符之间的间隙, 文本行, 通过缩小单词之间的差距,并且 段落 逐列扫描,然后关闭文本行之间的垂直间隙。

如果您无权访问任何公开此功能的文档图像分析库,您可以通过以下方式模仿效果:

使用形态运算(形态闭合),然后 对结果执行连通分量标记。

大多数图像处理库,例如 OpenCV,都提供了这样的功能。采用这种方法可能效率较低,因为您必须使用不同的文本间隙大小重新运行算法以实现不同级别的聚类,除非用户向您的应用程序提供文本间隙大小。

【讨论】:

【参考方案2】:

我认为您遇到了 OCR 的一个基本问题 - 这种类型的印刷设计使用空白作为有意义的分隔符,但 OCR 软件不/无法理解这一点。

这只是在黑暗中的疯狂尝试,但这是我会尝试的:

从左上角开始,构建一个可能是整个图像大小的 1-5% 的框。将它发送到 OCR,看看你是否得到了看起来有意义的东西。如果没有,请扩大直到你得到一些东西。

一旦你有了一些东西,开始以合理的单位扩展块,直到你停止获取新数据。希望您可以确定这一点是“有意义的空白”,现在您可以将此处理后的文本视为“一个块”并因此完成。现在从图像的下一个未处理部分开始,然后逐步完成,直到完成整个图像。

通过使用一组相互链接的扩展框,希望您只能将有意义的数据块组合在一起。使用您的示例,一旦您隔离徽标并对其进行处理(以及由此产生的乱码),下一个框将以 Noah 中的“N”开头。然后向右展开,直到得到全名。

完成此操作后,您可以再次访问,希望您会得到一个包含 Associate 中“A”的边界框,并获得整行。

我敢肯定,一次一个像素,所有这些运行到 OCR 会花费很长时间,但肯定会在“每个间隔扩展的块大小”和“处理量”之间进行权衡需要”。

我不明白为什么这种方法不适用于相对普通的印刷设计,例如常规风格的名片。

【讨论】:

你认为可以使用hOCR来查找文本的位置吗? @npor19 我想知道 OCR 程序本身是否确实存在某种反馈,也许允许映射来自何处的文本,这肯定会使事情变得更容易。但我对实现及其 API 不熟悉,因此您必须查阅相关文档。它会在某些方面使事情变得更容易,或者至少更有效......但程序可能没有提供这样定义的行为。【参考方案3】:

您可以尝试 HOCRText,它将所有扫描的单词以及该图像中每个单词的框架作为 xml 返回。

char *boxtext = _tesseract->GetHOCRText(0);

您可以解析该 xml 以获取每个单词及其框架。 否则,如果您需要,您可以在图像中提及应该进行 tesseract 扫描的框架。

_tesseract->SetRectangle(100, 100, 200, 200);

在调用识别之前设置此框架。因此 tesseract 将仅扫描该帧并在该帧返回文本。

【讨论】:

【参考方案4】:

Github 上有一个示例 ios 应用程序,它可能对您有所帮助:

https://github.com/danauclair/CardScan

他是怎么看名片的?他写了以下内容,(或者您可以在文件中阅读:https://github.com/danauclair/CardScan/blob/master/Classes/CardParser.m)

//  A class used to parse a bunch of OCR text into the fields of an ABRecordRef which can be added to the 
//  iPhone address book contacts. This class copies and opens a small SQLite databse with a table of ~5500
//  common American first names which it uses to help decipher which text on the business card is the name.
//
//  The class tokenizes the text by splitting it up by newlines and also by a simple " . " regex pattern.
//  This is because many business cards put multiple "tokens" of information on a single line separated by 
//  spaces and some kind of character such as |, -, /, or a dot.
//
//  Once the OCR text is fully tokenized it tries to identify the name (via SQLite table), job title (uses 
//  a set of common job title words), email, website, phone, address (all using regex patterns). The company
//  or organization name is assumed to be the first token/line of the text unless that is the name.
//
//  This is obviously a far from perfect parsing scheme for business card text, but it seems to work decently
//  on a number of cards that were tested. I'm sure a lot of improvements can be made here.

【讨论】:

以上是关于扫描名片 Tesseract 和 Leptonica iOS的主要内容,如果未能解决你的问题,请参考以下文章

使用Python进行名片OCR(识别姓名,职务,电话,Email邮箱)

如何告诉 tesseract 不要忽略单词之间的空格?

Android名片扫描识别系统SDK

iPhone SDK 的名片阅读器或 OCR 库

Android之扫描二维码和根据输入信息生成名片二维码

使用Tesseract和OpenCV构建自动收据扫描仪