【问题标题】:How to convert the background of the entire image to white when both white and black backgrounds are present?当同时存在白色和黑色背景时,如何将整个图像的背景转换为白色?
【发布时间】:2019-04-22 06:35:22
【问题描述】:

表单图像包含不同背景的文本。图像需要转换为一种背景(此处为白色),因此标题需要转换为黑色。

输入图像:

输出图像:

我的方法是检测网格(水平线和垂直线并将它们相加),然后将网格的每个部分裁剪成新的子图像,然后检查大部分像素颜色并进行变换因此。但是在实施之后,蓝色背景图像没有被检测到并被裁剪如下:

所以我试图将整个表单图像转换为一个背景,这样我就可以避免这种结果。

【问题讨论】:

    标签: python-3.x opencv


    【解决方案1】:

    这是一种不同的处理方式,可以处理 “反向视频”为黑色,而不是依靠一些颜色饱和度来找到它。

    #!/usr/bin/env python3
    
    import cv2
    import numpy as np
    
    # Load image, greyscale and threshold
    im = cv2.imread('form.jpg',cv2.IMREAD_GRAYSCALE)
    
    # Threshold and invert
    _,thr = cv2.threshold(im,127,255,cv2.THRESH_BINARY)
    inv   = 255 - thr
    
    # Perform morphological closing with square 7x7 structuring element to remove details and thin lines
    SE = np.ones((7,7),np.uint8)
    closed = cv2.morphologyEx(thr, cv2.MORPH_CLOSE, SE)
    # DEBUG save closed image
    cv2.imwrite('closed.png', closed)
    
    # Find row numbers of dark rows
    meanByRow=np.mean(closed,axis=1)
    rows = np.where(meanByRow<50)
    
    # Replace selected rows with those from the inverted image
    im[rows]=inv[rows]
    
    # Save result
    cv2.imwrite('result.png',im)
    

    结果如下:

    中间的closed 图像看起来像这样——我人为地添加了一个红色边框,这样你就可以在 Stack Overflow 的白色背景上看到它的范围:

    您可以阅读有关形态学的信息 here 和 Anthony Thyssen 的精彩描述 here

    【讨论】:

      【解决方案2】:

      这是一种可能的方法。如果转换为 HSV 色彩空间,蓝色阴影将显示出比黑色和白色更高的饱和度,所以...

      • 转换为 HSV
      • 查找每行的平均饱和度并选择平均饱和度超过阈值的行
      • 对这些行进行灰度化、反转和阈值化

      如果反向(突出)背景是黑色或白色以外的任何颜色,则此方法应该有效。根据您的示例,它假设您已将图像去偏,使其真正垂直/水平。

      在 Python 中可能看起来像这样:

      #!/usr/bin/env python3
      
      import cv2
      import numpy as np
      
      # Load image
      im = cv2.imread('form.jpg')
      
      # Make HSV and extract S, i.e. Saturation
      hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
      s=hsv[:,:,1]
      # Save saturation just for debug
      cv2.imwrite('saturation.png',s)
      
      # Make greyscale version and inverted, thresholded greyscale version
      gr = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
      _,grinv = cv2.threshold(gr,127,255,cv2.THRESH_BINARY_INV)
      
      # Find row numbers of rows with colour in them
      meanSatByRow=np.mean(s,axis=1)
      rows = np.where(meanSatByRow>50)
      
      # Replace selected rows with those from the inverted, thresholded image
      gr[rows]=grinv[rows]
      
      # Save result
      cv2.imwrite('result.png',gr)
      

      结果如下:

      饱和图像如下所示 - 请注意,饱和颜色(即蓝色)显示为浅色,其他所有颜色均显示为黑色:

      灰度反转图像如下所示:

      【讨论】:

      • 这种方法很好......但是黑白图像呢?如果您能用通用方法帮助我,那就太好了,因为我的输入表单可以是任何东西......甚至是黑白图像......
      • 我正在研究一种涉及findContours() 的不同技术,并计算每个轮廓的大小和平均颜色以找到严重黑框。如果我得到它的工作,我会发布一个新的答案。
      猜你喜欢
      • 2019-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 2011-08-07
      • 2015-10-21
      • 2016-08-17
      相关资源
      最近更新 更多