【问题标题】:Binarize bad background image using openCV Python使用openCV Python对坏背景图像进行二值化
【发布时间】:2021-02-28 06:00:54
【问题描述】:

我尝试使用以下步骤对 OCR 的护照图像进行二值化:

img = cv2.medianBlur(nid_aligned_image,3)
img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] 

此方法适用于更好的背景图像,但不适用于给定类型的图像。

这是输出,OCR 无法读取此内容

谁能给我推荐一个更好的方法?

【问题讨论】:

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


    【解决方案1】:

    我解决这个问题的方法是:


    1-应用自适应阈值

    2-应用形态变换

    3-应用位运算

    第 1 步:自适应阈值


    • 来自documentation

      • 如果图像在不同区域具有不同的照明条件。在这种情况下,自适应阈值可以提供帮助。在这里,该算法根据像素周围的小区域确定像素的阈值。因此,我们为同一图像的不同区域获得不同的阈值,从而为具有不同光照的图像提供更好的结果。

      • 总结:当用作阈值的全局值表现不佳时,您将使用自适应阈值。

      • img2 = cv2.imread("BESFs.png")
        gry2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
        
        flt = cv2.adaptiveThreshold(gry2,
                                     100, cv2.ADAPTIVE_THRESH_MEAN_C,
                                     cv2.THRESH_BINARY, 13, 16)
        
      • 结果:

    第 2 步:形态转换


    • 来自documentation

      • 它需要两个输入,一个是我们的原始图像,第二个称为结构元素或决定操作性质的内核

    • 我们需要定义一个内核(过滤器)来处理图像。

      • krn = np.ones((3, 3), np.uint8)
        
    • 我们将使用openingclosing

      • 开运算只是腐蚀后膨胀的另一个名称。它有助于消除噪音

      • 关闭与打开相反,先膨胀后腐蚀。它对于关闭前景物体内部的小洞或物体上的小黑点很有用。

    • opn = cv2.morphologyEx(flt, cv2.MORPH_OPEN, krn)
      cls = cv2.morphologyEx(opn, cv2.MORPH_CLOSE, krn)
      

    第 3 步:按位运算


    • 来自documentation

      • 它们在提取图像的任何部分时非常有用

      • gry2 = cv2.bitwise_or(gry2, cls)
        
      • 结果:

    • 现在如果我们使用pytesseract 来提取文本

      • txt = pytesseract.image_to_string(gry2)
        txt = txt.rstrip().split('\n\n')[1].split(' ')[1]
        print("Passport number: {}".format(txt))
        
      • 结果:

        • Passport number: BC0874168
          

    可选


    对于您未来的 OCR 问题,您可以尝试提高图像分辨率。例如:

    from PIL import Image
    
    img = Image.open("BESFs.png")
    h, w = img.size
    fct = min(1, int(1024.0/h))
    sz = int(fct * h), int(fct * w)
    im_rsz = img.resize(sz, Image.ANTIALIAS)
    im_rsz.save("out_dpi_300.png", dpi=(300, 300))
    

    对于这个问题,它没有任何效果,但也许它可以在未来帮助你。

    问题代码:

    import cv2
    import pytesseract
    import numpy as np
    
    img2 = cv2.imread("BESFs.png")
    gry2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    
    flt = cv2.adaptiveThreshold(gry2,
                                100, cv2.ADAPTIVE_THRESH_MEAN_C,
                                cv2.THRESH_BINARY, 13, 16)
    krn = np.ones((3, 3), np.uint8)
    opn = cv2.morphologyEx(flt, cv2.MORPH_OPEN, krn)
    cls = cv2.morphologyEx(opn, cv2.MORPH_CLOSE, krn)
    gry2 = cv2.bitwise_or(gry2, cls)
    txt = pytesseract.image_to_string(gry2)
    txt = txt.rstrip().split('\n\n')[1].split(' ')[1]
    print("Passport number: {}".format(txt))
    

    【讨论】:

    • 我应用了你的方法。它没有涵盖所有内容,但我将其用作 OCR 的替代方法。顺便说一句,谢谢你的回答
    • 你这是什么意思?唯一缺少的部分是“Republic of Bangladesh”和 30。您尝试过其他图片吗?
    • 覆盖所有意味着其他图像。但效果比以前好很多
    • 您是否再次尝试删除以下句子txt = txt.rstrip().split('\n\n)[1]..?也许它可能对其他图像效果更好
    • 我明白了,这是我能做的最好的,只使用一张示例图片
    猜你喜欢
    • 1970-01-01
    • 2017-07-06
    • 2014-10-29
    • 2014-03-08
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    相关资源
    最近更新 更多