【问题标题】:How to OCR image with Tesseract如何使用 Tesseract 对图像进行 OCR
【发布时间】:2020-01-25 22:30:27
【问题描述】:

我开始学习 OpenCV 和 Tesseract,但对于一个看似非常简单的示例却遇到了麻烦。

这是我正在尝试 OCR 的图像,上面写着“171 m”:

我做了一些预处理。由于蓝色是文本的主要颜色,我提取了蓝色通道并应用了简单的阈值。

img = cv2.imread('171_m.png')[y, x, 0]
_, thresh = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY_INV)

生成的图像如下所示:

然后将其放入 Tesseract 中,psm 7 用于单行:

text = pytesseract.image_to_string(thresh, config='--psm 7')
print(text)
>>> lim

我也尝试限制可能的字符,它变得更好了一点,但并不完全。

text = pytesseract.image_to_string(thresh, config='--psm 7 -c tessedit_char_whitelist=1234567890m')
print(text)
>>> 17m
OpenCV v4.1.1.
Tesseract v5.0.0-alpha.20190708

任何帮助表示赞赏。

【问题讨论】:

    标签: python image opencv ocr tesseract


    【解决方案1】:

    在将图像放入 Pytesseract 之前,预处理会有所帮助。所需文本应为黑色,而背景应为白色。这是一种方法

    • 将图像转换为灰度并放大图像
    • 高斯模糊
    • 大津的门槛
    • 反转图像

    转换为灰度后,我们使用imutils.resize() 和高斯模糊放大图像。从这里我们Otsu的阈值得到二值图像

    如果您有嘈杂的图像,另外一个步骤是使用形态学运算来平滑或去除噪声。但是由于您的图像足够干净,我们可以简单地反转图像以获得我们的结果

    使用--psm 6从 Pytesseract 输出

    171 米

    import cv2
    import pytesseract
    import imutils
    
    pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
    
    image = cv2.imread('1.png',0)
    image = imutils.resize(image, width=400)
    blur = cv2.GaussianBlur(image, (7,7), 0)
    thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    result = 255 - thresh 
    
    data = pytesseract.image_to_string(result, lang='eng',config='--psm 6')
    print(data)
    
    cv2.imshow('thresh', thresh)
    cv2.imshow('result', result)
    cv2.waitKey()
    

    【讨论】:

      【解决方案2】:

      免责声明:这不是解决方案,只是部分解决此问题的试验。

      只有在您事先知道图像中存在的字符数时,此过程才有效。这是试用代码:

      img0 = cv2.imread('171_m.png', 0)
      adap_thresh = cv2.adaptiveThreshold(img0, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
      text_adth = pytesseract.image_to_string(adap_thresh, config='--psm 7')
      

      自适应阈值处理后,生成的图像是这样的:

      Pytesseract 给出的输出为:

      171 mi.
      

      现在,如果您提前知道存在的字符数,您可以对 pytesseract 读取的字符串进行切片,并获得所需的输出为 '171m'

      【讨论】:

        【解决方案3】:

        我认为您的图像不够清晰,因此我应用了How do I increase the contrast of an image in Python OpenCV 中描述的过程来首先锐化您的图像,然后提取蓝色层并运行 tesseract。

        我希望这会有所帮助。

        import cv2
        import pytesseract 
        
        img = cv2.imread('test.png') #test.png is your original image
        s = 128
        img = cv2.resize(img, (s,int(s/2)), 0, 0, cv2.INTER_AREA)
        
        def apply_brightness_contrast(input_img, brightness = 0, contrast = 0):
        
            if brightness != 0:
                if brightness > 0:
                    shadow = brightness
                    highlight = 255
                else:
                    shadow = 0
                    highlight = 255 + brightness
                alpha_b = (highlight - shadow)/255
                gamma_b = shadow
        
                buf = cv2.addWeighted(input_img, alpha_b, input_img, 0, gamma_b)
            else:
                buf = input_img.copy()
        
            if contrast != 0:
                f = 131*(contrast + 127)/(127*(131-contrast))
                alpha_c = f
                gamma_c = 127*(1-f)
        
                buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c)
        
            return buf
        
        out = apply_brightness_contrast(img,0,64)
        
        b, g, r = cv2.split(out) #spliting and using just the blue
        
        pytesseract.image_to_string(255-b, config='--psm 7 -c tessedit_char_whitelist=1234567890m') # the 255-b here because the image has black backgorund and white numbers, 255-b switches the colors
        

        【讨论】:

        • 用opencv 4.1版(s, s/2)需要(s, int(s/2)),否则给TypeError: integer argument expected, got float
        • 感谢您指出这一点,我将编辑答案。否则,它对你有用吗?你得到正确答案了吗?
        猜你喜欢
        • 2015-05-10
        • 2021-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-13
        • 2015-10-17
        相关资源
        最近更新 更多