需要Tesseract收据扫描建议

23
我曾多次为各种OCR项目与Tesseract奋斗过,今天我发现了一个使用案例,本以为这会是它的一大优势,但经过多个小时的尝试,仍然无法满足需求。我想在这里提出问题,看看是否有其他人能提供解决方案。
今天早上,我妻子问我是否有简便方法可以扫描她从沃尔玛收到的收据,并逐渐建立类别和特定物品的花费历史记录,以便我们可以进行趋势分析并轻松深入地了解支出去向。起初我觉得这是一个非常困难的任务,但经过一些调查,我发现了一些东西,让我觉得这是可以实现的:
Wal-Mart的收据通常结构良好,易于阅读。它们甚至包括每个项目的UPC(潜在用于UPC数据库的查找?),并且似乎使用F或I对食品进行分类(不确定差异是什么),还有一个税收代码列,这可能会在我了解代码含义的秘密时证明有用。
我进一步发现,有某种Wal-Mart物品查找API,我可能可以获得访问权限,这将在UPC查找中证明有用。
他们为智能手机提供了一个应用程序,可以扫描每张收据上印刷的QR码。该应用程序会从其服务器上查找收据上的“TC”代码,并下载整个详细列表。它会向您显示收据的优秀图形表示,包括所有项目的缩略图和成本等。如果此应用程序只需对收据进行分类和汇总,那就太完美了!但遗憾的是,这不是该应用程序的目的...
谜题的最后一块是,您可以导出计算机生成的收据PNG图像,以便保存并丢弃纸质版本。对我而言,这是重点,因为这些PNG是由计算机创建的,因此不受拍照或扫描纸质收据的问题影响。

以下是其中一个示例(稍作编辑以隐藏某些区域,但其余内容与应用程序获取的完全相同):

https://postimg.cc/image/s56o0wbzf/

你可以看到文本的重要部分完美地对齐在5列中,这才是这个问题的关键。如何让 Tesseract 将其准确地 OCR 成文本。我有很多想法可以从这里开始,但所有的一切都始于 OCR!
我自己最接近的例子是这个:

http://pastebin.com/nuZJBVg8

我使用了psm6和字符限制集,强制它只能使用大写字母、数字和少量符号:
tessedit_char_whitelist 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ#()/*@%-.

乍一看,OCR似乎几乎匹配。但是当你深入挖掘时,你会发现它整体上失败得相当惨。3和8几乎总是错误的。5和6也是如此。然后有时它会完全跳过字符或开始崩溃(例如示例中的31+行)。它开始将2看作1,甚至会漏掉字符。第33行的SO PIZZA应该是“2.82”,但输出为“32”。
我已经尝试在图像上进行一些预处理,使字符更加粗细,确保它是纯黑色和白色,但我的所有努力都没有比来自沃尔玛的原始图像和上述命令更接近。
理想情况下,由于这是一个非常结构化的PNG文件,宽度可能始终相同,因此我希望能够通过像素宽度定义列,以便Tesseract将每个列视为独立的。我尝试过研究这个问题,但我看到的UZN文件对于像素宽度来说不太适用,而且它们似乎高度也是一个因素,这对于这些文件来说是不起作用的,因为高度始终会有所变化。
此外,我需要找出如何训练Tesseract以100%准确地识别数字(字母并不重要)。我开始研究如何训练程序,但说实话,由于文档中的培训范围更多地是为了使其识别整个语言而不仅仅是10个数字,因此很快就超出了我的能力范围。
最终的解决方案将是一个管道命令链,它从应用程序中获取原始PNG并将5列数据从收据的重要部分返回给我CSV。我不指望这个问题能够得到解决,但任何帮助引导我走向解决方案都将不胜感激!此时,我只是不想再次被Tesseract折磨,所以我决心找到掌握她的方法!

2
Jim,根据我使用Tesseract的经验,你可以尝试一些技巧:1)通过调整大小将图像分辨率更改为原始图像大小的150%或75%(尝试不同的因素),我猜测Tesseract是针对扫描文档的某些DPI值(300、600、900)进行训练的,有时需要更接近这些值以获得更好的OCR结果。2)将图像分段成仅包含文本或数字的列,并使用相应的白名单。3)查看FineReader等商业解决方案以进行比较(是否可行?)。 - RevJohn
哇,这确实极大地提高了准确性!我还没有检查每一个数字,但现在看起来好像已经达到了100%,所以谢谢你!我按照你的建议增加了150%。 - Jim Sanders
此外,我尝试手动将图像分段成列,并独立地对其进行OCR(也放大了150%),然后我能够使用Linux命令paste创建我的CSV文件。但是,由于它们都被单独OCR处理,所以我在列的对齐方面遇到了严重的问题。有人有关于如何确保OCR结果之间对齐的提示吗?我的下一个想法是使用正则表达式来打破列,利用UPC始终是由空格包围的12个数字和价格始终是由空格包围的1个或多个数字+句点+ 2个数字的事实。 - Jim Sanders
2个回答

17

我最终把这个完善了一下,结果还不错,所以我想把它发布出来,以防有其他人也会觉得有用。

我没有必要拆分任何图像,相反,我使用了正则表达式,因为沃尔玛的收据是如此可预测。

我使用了PowerShell脚本在Windows上运行转换命令和正则表达式查找与替换:

# -----------------------------------------------------------------
# Script: ParseReceipt.ps1
# Author: Jim Sanders
# Date: 7/27/2015
# Keywords: tesseract OCR ImageMagick CSV
# Comments:
#   Used to convert a Wal-mart receipt image to a CSV file
# -----------------------------------------------------------------
param(
    [Parameter(Mandatory=$true)] [string]$image
) # end param

# create output and temporary files based on input name
$base = (Get-ChildItem -Filter $image -File).BaseName
$csvOutfile = $base + ".txt"
$upscaleImage = $base + "_150.png"
$ocrFile = $base + "_ocr"

# upscale by 150% to ensure OCR works consistently
convert $image -resize 150% $upscaleImage

# perform the OCR to a temporary file
tesseract $upscaleImage -psm 6 $ocrFile

# column headers for the CSV
$newline = "Description,UPC,Type,Cost,TaxType`n"
$newline | Out-File $csvOutfile

# read in the OCR file and write back out the CSV (Tesseract automatically adds .txt to the file name)
$lines = Get-Content "$ocrFile.txt"

Foreach ($line in $lines) {
    # This wraps the 12 digit UPC code and the price with commas, giving us our 5 columns for CSV
    $newline = $line -replace '\s\d{12}\s',',$&,' -replace '.\d+\.\d{2}.',',$&,' -replace ',\s',',' -replace '\s,',','
    $newline | Out-File -Append $csvOutfile
}

# clean up temporary files
del $upscaleImage
del "$ocrFile.txt"

生成的文件需要在Excel中打开,然后使用“文本分列”功能运行,以避免自动将UPC代码转换为数字而破坏它们。这是一个众所周知的问题,我不会深入讨论,但有很多处理方法,我选择了这种稍微更加手动的方式。

如果能以简单的 .csv 文件双击打开就好了,但是我找不到一个很好的方法来实现这一点,因为那样会更进一步损坏UPC码,比如将它们包装成这种格式:

 "=""12345"""
那确实管用,但我希望UPC代码只是数字本身作为文本出现在Excel中,以防我以后能够针对沃尔玛API进行查找。无论如何,这是导入和一些快速格式化后它们的外观:https://s3.postimg.cc/b6cjsb4bn/Receipt_Excel.png 我仍然需要清理一些不是行项目的行上的垃圾,但这只需要几秒钟,所以并不太困扰我。感谢@RevJohn给出正确方向的提示,我没有想到尝试简单地缩放图像,但这使Tesseract的效果大为改善!

2
是的,分辨率很重要。我过去做过一些OCR准确性与图像分辨率的实验:你得到的不是一个递增的图形(更高的分辨率更好),而是一个具有局部极大值的图形,这些极大值对应着训练中使用的DPI分辨率(我猜测)。上下缩放图像可以帮助提高准确性;其他OCR引擎也是如此。 - RevJohn

15

识别收据上的文本是OCR难以处理的最困难的问题之一。

原因有很多:

  • 收据用廉价纸张和廉价打印机打印,为了使它们便宜,而不是易读!
  • 它们有非常大量的密集文本(特别是沃尔玛的收据)
  • 现有的OCR引擎几乎完全是针对非收据数据进行训练的(书籍、文档等)
  • 收据结构介于表格和自由形式之间,这对于任何排版引擎来说都很困难。

您最好执行以下操作:

  • 分析输入图像。如果它们很难被肉眼阅读,那么它们对于Tesseract来说也很难阅读。
  • 执行其他图像预处理。图像缩放(0.5倍、1.5倍、2倍)有时会帮助很多。清除现有噪声也有所帮助。
  • Tesseract培训。这并不难 :)
  • OCR结果后处理以确保布局。

布局最好通过分析结果的几何形状来执行,而不是使用正则表达式。如果OCR存在错误,则正则表达式会有问题。例如,使用几何形状,您可以找到UPC号码的良好候选项,通过字符中心绘制一条线,然后您就知道哪个价格属于该UPC。

此外,一些商业解决方案对收据扫描进行了定制,甚至可以在移动设备上运行得非常快速。

我正在与的公司MicroBlink合作,拥有适用于移动设备的OCR模块。如果您使用iOS,可以使用CocoaPods轻松尝试它

pod try PPBlinkOCR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接