Tesseract 输出从非常清晰的图像中更改、添加和删除数字

Posted

技术标签:

【中文标题】Tesseract 输出从非常清晰的图像中更改、添加和删除数字【英文标题】:Tesseract output changing, adding, and removing numbers from very clear image 【发布时间】:2021-12-04 00:39:05 【问题描述】:

我正在开发一个程序,该程序使用网络摄像头使用 pytesseract 读取屏幕上不断变化的数字(长篇故事)。它拍摄整个屏幕的图像,然后使用存储在名为“roi”的列表中的预定坐标切割出需要记录的每个数字(其中有 23 个)。还有一些其他步骤,但这是最重要的部分。目前它正在不断地添加、删除和更改数字,但不是始终。下面是一些例子:

它错误地读作“32.0”

它正确读取为 '52.0'

它错误地读作“39.3”

它错误地读作“2499.1”

这些图像已经使用 OpenCV 进行了处理,这就是 roi 集中所有图像的样子。根据其他答案,我将其二值化,尝试清理边缘,并在图像周围放置白色边框(参见代码)。

此程序每 30 秒读取一次屏幕,有时会正确,有时会出错。很多时候它喜欢把5s变成3s,3s变成5s,5s变成9s。有时它只是错过或完全添加数字。下面是我处理图像的代码。

pytesseract.pytesseract.tesseract_cmd = #tesseract file path
scale = 1.4
img = cv2.imread(#image file path#)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.rotate(img, cv2.ROTATE_180)
width = int(img.shape[1] / scale)
height = int(img.shape[0] / scale)
dim = (width, height)
img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)                                    
cv2.destroyAllWindows()

myData = []
cong = r'--psm 6 -c tessedit_char_whitelist=+0123456789.-'

for x,r in enumerate(roi):                                                                 
    imgCrop = img[r[0][1]:r[1][1], r[0][0]:r[1][0]]        
    scalebig = 0.2
    wid = int(imgCrop.shape[1] / scalebig)
    hei = int(imgCrop.shape[0] / scalebig)
    newdims = (wid, hei)
    imgCrop = cv2.resize(imgCrop, newdims)

    imgCrop = cv2.threshold(imgCrop,155,255,cv2.THRESH_BINARY)[1]

    kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))                              
    imgCrop = cv2.morphologyEx(imgCrop, cv2.MORPH_CLOSE, kernel2, iterations=2)

    value = [255,255,255]
    imgCrop = cv2.copyMakeBorder(imgCrop, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, value = value)

    datapoint = pytesseract.image_to_string(imgCrop, lang='eng', config=cong)
    myData.append(datapoint)

输出是我上面链接的图片。

我已经研究过微调它,但我有一台 Windows 机器,我似乎找不到好的教程。我不是一个专业的程序员,我花了 2 个月的时间自学 Python 来做到这一点,但是 Tesseract 的机器学习方面让我感到困惑,我不知道如何解决非常不一致的读数。如果您需要任何进一步的信息,请询问,我很乐意告诉您。

编辑:添加了一些更多错误读取的图像以供参考

【问题讨论】:

Use pytesseract OCR to recognize text from an image 请发布 1-2 张失败的图片。请发布原始图像(只是 roi)-也许会有更好的预处理建议。您也可以尝试使用不同的psm,例如7 或 8(行/字)。 @user898678 不幸的是,由于公司 IP 的原因,我无法发布完整的图像,但由于屏幕上还有其他文本和数字,这似乎是仅隔离我需要的数字的最佳方法。我将发布更多阅读不正确的图像。我尝试将 PSM 设置更改为其他几个具有相似/更差结果的选项。 @nathancy 我已经尝试了该帖子中的建议,结果与我现在得到的结果相似。 我写道:原始图像(只是 roi)。 roi = 感兴趣区域。 【参考方案1】:
    确保使用正确的图像格式(jpeg 是错误的 OCR 格式) 对于 tesseract LSTM 引擎,请确保字母大小不大于 35 磅。

使用 tesseract best_tessdata 我得到了这些结果:

tesseract 593_small.png -
59.3

tesseract 520_small.png -
52.0

tesseract 2491_small.png -
249.1

【讨论】:

感谢您的回答,我不知道它需要小于 35pt。请问你把图片缩放到什么尺寸?我尝试通过保持原始图像大小来缩小我的尺寸,这让事情变得更糟,所以我想我必须放大它们来进行预处理,然后再次缩小它们以使用 tesseract 读取它们,但我是不知道要缩小到什么尺寸。您正在使用哪个 tess_best traindata/您从哪里得到它?现在我正在使用来自this Github page 的 eng.traindata。我现在使用 .bmp 的图像,我应该切换到 .png 吗? 我在 infranview 中使用关于预期高度(+ 边框)的设置缩小了它 - 这只是一个猜测...... IMO 22-35 pt 之间的所有东西都应该没有问题(可能更小)。我更喜欢能够存储 dpi 信息的格式(字母大小为 22-35 的格式为 300)——我不确定 bmp 是否可以做到。 将图像缩小到那个大小似乎有点帮助,但我仍然无法获得一致的结果。我意识到它不会是 100% 完美的,但尤其是 249.1,我无法正确阅读。使图像太小会导致更频繁地正确,但 roi 中最初正确的其他几个数字是错误的,反之亦然(不幸的是,我不能在 cmets 中包含图像,否则我会告诉你)。我会将您的答案标记为最佳,但我仍然希望有更多方法来改进我的输出。

以上是关于Tesseract 输出从非常清晰的图像中更改、添加和删除数字的主要内容,如果未能解决你的问题,请参考以下文章

从图像中去除背景噪音,使 OCR 的文本更清晰

如何使用图像的 tesseract 输出从另一个图像创建可搜索的 pdf

iOS Tesseract OCR 图像准备

如何在 tesseract 中保留文档结构

为啥 tesseract 无法从这个简单的图像中读取文本?

训练 Tesseract 3 从燃气表的真实图像中识别数字