【问题标题】:Reading numbers using PyTesseract使用 PyTesseract 读取数字
【发布时间】:2020-11-07 06:07:06
【问题描述】:

我正在尝试从图像中读取数字,但无法找到使其始终如一地工作的方法(并非所有图像都有数字)。这些是图片:

(这里是相册的链接,以防图片失效)

这是我用来在图像上运行 tesseract 的命令:pytesseract.image_to_string(image, timeout=2, config='--psm 13 --oem 3 -c tessedit_char_whitelist=0123456789')。我尝试了多种配置,但这似乎效果最好。

就预处理而言,这是最好的:

    gray = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2GRAY)
    gray = cv2.bilateralFilter(gray, 11, 17, 17)
    im_bw = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY_INV)[1]

这适用于除第三张以外的所有图像。为了解决第三张图像中的线条问题,我尝试使用 cv2.Canny 和一个相当大的阈值来获取边缘,但是当将它们拉回来时,即使它得到了超过 95%每个数字的边缘,tesseract 无法正确读取它们。

我也尝试过调整图像大小,使用 cv2.morphologyEx,模糊它等。我找不到一种方法让它适用于每种情况。

谢谢。

【问题讨论】:

    标签: python opencv image-processing python-tesseract


    【解决方案1】:

    cv2.resize 一直为我使用 INTER_CUBIC 插值。

    将最后一步添加到预处理很可能会解决您的问题。

    im_bw_scaled = cv2.resize(im_bw, (0, 0), fx=4, fy=4, interpolation=cv2.INTER_CUBIC)

    你可以玩弄天平。我已经使用了上面的“4”。

    编辑:

    以下代码非常适用于您的图像,甚至是特殊字符。请尝试使用您的其余数据集。缩放、OTSU 和侵蚀是最好的组合。

    import cv2
    import numpy
    import pytesseract
    
    pytesseract.pytesseract.tesseract_cmd = "<path to tesseract.exe>"
    
    # Page segmentation mode, PSM was changed to 6 since each page is a single uniform text block.
    custom_config = r'--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789'
    
    # load the image as grayscale
    img = cv2.imread("5.png",cv2.IMREAD_GRAYSCALE)
    
    # Change all pixels to black, if they aren't white already (since all characters were white)
    img[img != 255] = 0
    
    # Scale it 10x
    scaled = cv2.resize(img, (0,0), fx=10, fy=10, interpolation = cv2.INTER_CUBIC)
    
    # Retained your bilateral filter
    filtered = cv2.bilateralFilter(scaled, 11, 17, 17)
    
    # Thresholded OTSU method
    thresh = cv2.threshold(filtered, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
    
    # Erode the image to bulk it up for tesseract
    kernel = numpy.ones((5,5),numpy.uint8)
    eroded = cv2.erode(thresh, kernel, iterations = 2)
    
    pre_processed = eroded
    
    # Feed the pre-processed image to tesseract and print the output.
    ocr_text = pytesseract.image_to_string(pre_processed, config=custom_config)
    if len(ocr_text) != 0:
        print(ocr_text)
    else: print("No string detected")
    

    【讨论】:

    • 谢谢!你使用了什么阈值?
    • 使用 otsu 方法可以很好地处理阈值范围(最小和最大限制),并让该方法找到最佳阈值。你会在这里找到一个很好的解释:stackoverflow.com/a/23260699
    • 谢谢!使用您的代码并在 230 处添加自定义阈值适用于我的所有测试用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2021-04-14
    • 2020-10-23
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    • 2023-02-07
    相关资源
    最近更新 更多