我正在尝试使用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]);
卡的图片
这是输出
您可以看到准确性不是100%,这不是我担心的,我认为我可以通过一些简单的每个处理来解决这个问题。但是,如果您注意到它会将两个文本块混合在底部的两个文本块,从而将地址分开,可能是其他卡片上的其他信息。
我如何使用Leptonica(或其他可能的OpenCV)以某种方式对文本进行分组?可能将图像上的文本区域分别发送到Tesseract进行扫描?我一直在这个问题上遇到一段时间,欢迎任何可能的解决方案!
我建议使用一种称为"运行长度平滑算法"的算法"(RLSA)。该算法用于许多文档图像处理系统中,尽管并非每个系统都将其作为API的一部分展示。
原始论文于1982年发表,需要付款。但是,许多其他论文都在文档图像处理中引用了同样的算法,您可以轻松地找到实现详细信息和改进。
这样的论文是:http://www.sciencecendirect.com/science/article/pii/s0262885609002005
基本思想是通过行扫描文档图像,记录字母之间的差距的宽度。
然后,可以通过在间隙的宽度上过滤并将小间隙设置为与文本相同的颜色来结合附近的文本字符。结果将是表示:
的大型连接组件- 单词,
- 通过缩小字符之间的差距,
- 文本行,
- 通过缩小单词之间的差距,
- 段落
- 通过列扫描,然后缩小文本线之间的垂直间隙。
如果您无法访问显示此功能的任何文档图像分析库,则可以通过以下方式模仿效果:
- 使用形态学操作(形态结束),然后
- 在结果上执行连接的组件标记。
大多数图像处理库,例如OpenCV,都提供了这样的功能。采用这种方法可能不太效率,因为您必须使用不同的文本差距大小重新运行算法以实现不同级别的聚类,除非用户为您的应用程序提供了文本差距大小。
我认为您已经遇到了OCR的基本问题 - 这种类型的印刷设计使用空间作为有意义的分界符,但是OCR软件不/无法理解那。
这只是黑暗中的狂野刺伤,但这是我尝试的:
从左上方开始,构建一个盒子,也许是整个图像的大小的1-5%。将其发送给OCR,看看您是否得到了有意义的回音。如果没有,请扩展,直到您得到东西。
一旦有了一些东西,就开始以合理的单位扩展块,直到停止获取新数据为止。希望您可以决定这一点是"有意义的空白",现在您可以将此处理过的文本视为"一个块",从而完成。现在,从图像的下一个未经处理的部分开始,从而完成整个图像完成之前。
。通过使用一组相互联系的扩展框,希望您只会得到有意义的数据块。使用您的示例,一旦您隔离了徽标并处理它(以及由此产生的Gibberish),下一个框将以Noah的" N"开头。然后,您向右扩展直到获得全名。
完成此操作,您可以再次进行,希望您会得到一个包含" A"中的" A"并获得整个行的边界框。
我敢肯定,一个像素一次会花费太长时间,但是所有这些运行到OCR,但肯定会在"每间隔扩展的块大小"one_answers"处理量"上进行权衡需要"。
我不明白为什么这种方法对相对正常的打印设计不起作用,例如普通风格的名片。
您可以尝试使用hocrtext,以返回所有被扫描的单词以及该图像中每个单词的帧作为XML。
char *boxtext = _tesseract->GetHOCRText(0);
您可以解析XML以获取每个单词及其框架。否则,如果需要,您可以提及应该扫描的图像中的框架。
_tesseract->SetRectangle(100, 100, 200, 200);
在呼叫识别之前,请先设置此框架。因此,Tesseract仅扫描该帧并在该框架上返回文本。
github上有一个iOS应用程序,可以对您有所帮助:
https://github.com/danauclair/cardscan
他如何阅读名片?他写下了以下内容(或者您可以在文件中阅读:https://github.com/danauclair/cardscan/blob/master/master/classes/cardparses/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.