【问题标题】:Pytesseract doesn't recognize decimal pointsPytesseract 不识别小数点
【发布时间】:2021-06-04 21:24:57
【问题描述】:

我正在尝试读取此图像中还包含小数点和小数的文本

这样:

img = cv2.imread(path_to_image)
print(pytesseract.image_to_string(img))

我得到的是:

73-82
Primo: 50 —

我也尝试指定意大利语,但结果非常相似:

73-82 _
Primo: 50

在stackoverflow上搜索其他问题,我发现可以通过使用白名单来改进十进制数的读取,在本例中为tessedit_char_whitelist='0123456789.',但我也想读取图像中的单词。关于如何提高十进制数的阅读的任何想法?

【问题讨论】:

    标签: python opencv ocr tesseract python-tesseract


    【解决方案1】:

    我建议将每行文本作为单独的图像传递 tesseract。
    由于某种原因,它似乎解决了小数点问题......

    • 使用cv2.threshold将图像从灰度转换为黑白。
    • 使用具有超长水平内核的cv2.dilate 形态学运算(跨水平方向合并块)。
    • 使用查找轮廓 - 每个合并的行都将位于单独的轮廓中。
    • 找到轮廓的边界框。
    • 根据 y 坐标对边界框进行排序。
    • 迭代边界框,并将切片传递给pytesseract

    代码如下:

    import numpy as np
    import cv2
    import pytesseract
    
    pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'  # I am using Windows
    
    path_to_image = 'image.png'
    
    img = cv2.imread(path_to_image, cv2.IMREAD_GRAYSCALE)  # Read input image as Grayscale
    
    # Convert to binary using automatic threshold (use cv2.THRESH_OTSU)
    ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    
    # Dilate thresh for uniting text areas into blocks of rows.
    dilated_thresh = cv2.dilate(thresh, np.ones((3,100)))
    
    
    # Find contours on dilated_thresh
    cnts = cv2.findContours(dilated_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]  # Use index [-2] to be compatible to OpenCV 3 and 4
    
    # Build a list of bounding boxes
    bounding_boxes = [cv2.boundingRect(c) for c in cnts]
    
    # Sort bounding boxes from "top to bottom"
    bounding_boxes = sorted(bounding_boxes, key=lambda b: b[1])
    
    
    # Iterate bounding boxes
    for b in bounding_boxes:
        x, y, w, h = b
    
        if (h > 10) and (w > 10):
            # Crop a slice, and inverse black and white (tesseract prefers black text).
            slice = 255 - thresh[max(y-10, 0):min(y+h+10, thresh.shape[0]), max(x-10, 0):min(x+w+10, thresh.shape[1])]
    
            text = pytesseract.image_to_string(slice, config="-c tessedit"
                                                              "_char_whitelist=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-:."
                                                              " --psm 3"
                                                              " ")
    
            print(text)
    

    我知道这不是最通用的解决方案,但它可以解决您发布的示例。
    请将答案视为概念性解决方案 - 找到可靠的解决方案可能非常具有挑战性。


    结果:

    扩张后的阈值图像:

    第一个切片:

    第二个切片:

    第三片:

    输出文本:

    7.3-8.2

    Primo:50

    【讨论】:

    • 谢谢,这真的很棒,因为它可以消除图像中的外部噪音。我想知道它是否也适用于超过 3 行的图像,因为我正在处理一堆图像,而且大多数时候我的图像少于或多于 3 行
    • 当然,它适用于超过 3 行,但在很多情况下该解决方案不起作用。示例:我使用了一些不适用于所有情况的特定常量值。当文本未按水平行排列时,它将不起作用。还有 Tesseract 的限制——我不知道 Tesseract OCR 无法识别小数点的情况......
    • 我试过了,它适用于更多或更少的行,但在某些情况下,Tessaract 无法识别采用单行而不是整个标题的文本
    • 您将不得不对其进行调试。您可以从显示传递给pytesseract.image_to_string 的每个“切片”开始。添加cv2.imshow('slice', slice)cv2.waitKey()(在pytesseract.image_to_string之前添加)。确保“切片”图像包含预期的文本。您也可以像 Ahx 建议的那样尝试下采样。
    • 是的,我做到了,但由于某种原因,如果切片包含“Si: 10”Tesseract 将其读取为空字符串。现在如果不显示图形示例就很难解释,也许我会提出一个新问题。另一方面,您的代码运行良好
    【解决方案2】:

    您可以通过down-sampling 图片轻松识别。

    如果您下采样 0.5,结果将是:

    现在如果你阅读:

    7.3 - 8.2
    Primo: 50
    

    我使用pytesseract 0.3.7版本得到结果(current

    代码:


    # Load the libraries
    import cv2
    import pytesseract
    
    # Load the image
    img = cv2.imread("s9edQ.png")
    
    # Convert to the gray-scale
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Down-sample
    gry = cv2.resize(gry, (0, 0), fx=0.5, fy=0.5)
    
    # OCR
    txt = pytesseract.image_to_string(gry)
    print(txt)
    

    说明:


    输入图像包含一些人工制品。您可以在图像的右侧看到它。另一方面,当前图像非常适合 OCR 识别。当图像中的数据不可见或损坏时,您需要使用预处理方法。请阅读以下内容:

    【讨论】:

    • 谢谢!我在阅读图像之前进行了 2 的上采样,因为我读到它可以提高识别率,但我想它太多了
    • 您在阅读图像之前进行了上采样?你在上采样之前尝试过 OCR 吗?
    • 是的,但在某些情况下,上采样帮助我正确读取图像
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    相关资源
    最近更新 更多