【问题标题】:Digit recognition in python (OpenCV and pytesseract)python中的数字识别(OpenCV和pytesseract)
【发布时间】:2020-01-21 16:53:49
【问题描述】:

我目前正在尝试从小屏幕截图中检测数字。但是,我发现准确性很差。我一直在使用 OpenCV,图像以 RGB 格式捕获并转换为灰度,然后使用全局值执行阈值处理(我发现自适应效果不太好)。

这是其中一个数字的灰度示例,后面是阈值保持后的图像示例(数字范围为 1-99)。请注意,图像的初始屏幕截图非常小,因此被放大了。

非常感谢任何有关如何使用 OpenCV 或完全不同的系统来提高准确性的建议。下面包含一些代码,该函数是通过屏幕截图的 RGB 数字来传递的。

def getNumber(image):
    image = cv2.resize(image, (0, 0), fx=3, fy=3)
    img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    thresh, image_bin = cv2.threshold(img, 125, 255, cv2.THRESH_BINARY)

    image_final = PIL.Image.fromarray(image_bin)

    txt = pytesseract.image_to_string(
        image_final, config='--psm 13 --oem 3 -c tessedit_char_whitelist=0123456789')
    return txt

【问题讨论】:

  • 你试过什么?什么不起作用?显示您的代码。请阅读此论坛的帮助部分,了解如何提出好问题。
  • 道歉@fmw42。在底部包含当前函数。
  • 您可以尝试自适应阈值,或者您可以尝试使用一些形态学来尝试关闭白色字母。

标签: python opencv machine-learning image-processing ocr


【解决方案1】:

这是我可以改进的地方,使用 otsu 阈值比给出任意值更有效地将文本与背景分开。 Tesseract 对白色背景上的黑色文本效果更好,而且我还添加了填充,因为如果字符太靠近边界,则 tesseract 难以识别字符。

这是最终图像 [final_image][1] 并且 pytesseract 设法读取“46”

import cv2,numpy,pytesseract
def getNumber(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # Otsu Tresholding automatically find best threshold value
    _, binary_image = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
    
    # invert the image if the text is white and background is black
    count_white = numpy.sum(binary_image > 0)
    count_black = numpy.sum(binary_image == 0)
    if count_black > count_white:
        binary_image = 255 - binary_image
        
    # padding
    final_image = cv2.copyMakeBorder(image, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=(255, 255, 255))
    txt = pytesseract.image_to_string(
        final_image, config='--psm 13 --oem 3 -c tessedit_char_whitelist=0123456789')

    return txt

函数执行为:

>> getNumber(cv2.imread(img_path))

编辑:请注意,您不需要此行:

image_final = PIL.Image.fromarray(image_bin)

因为您可以将 numpy 数组格式的图像(使用 cv2)传递给 pytesseractr,而 Tesseract 的准确度只会下降 35 像素以下的字符(而且更大,35px 高度实际上是最佳高度)所以我没有调整它的大小. [1]:https://i.stack.imgur.com/OaJgQ.png

【讨论】:

  • 谢谢!它使用您的代码成功读取 46,但在测试时未能读取 47。从为 47 生成的最终图像中,我很惊讶它未能读取它。我还可以采取任何其他步骤来提高准确性吗?
  • 您可以尝试重新采样到更大的尺寸。这可能会给你一些回旋的空间来做一些smoothingmorphology 操作。作为最后的手段,如果您的图像具有相同的字体和相同的大小,您可以尝试template matching 单个数字。
  • 好吧,您的特定字体/大小并不容易,就像其他评论说您可以使用 opencv 侵蚀/扩张形态学操作一样,还可以在对灰度图像进行阈值处理之前对灰度图像应用中值模糊。
猜你喜欢
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
相关资源
最近更新 更多