【问题标题】:Fill transparent holes in an image with Python用 Python 填充图像中的透明孔
【发布时间】:2021-03-10 05:08:02
【问题描述】:

由于删除了一些写在原始图像上的字母,我的图像具有相对较小的孔。还有其他有意义的洞,我不想碰它们。我想“检测并填充相邻的颜色”这些小工件。这是我的示例图像(请注意,这里的白色不是真正的白色,而是透明的),下面是我想要得到的结果:

此外,我附上带有文本的原始图像的快照(以防有人发现从这一点开始处理图像更容易,而不是我上面描述的透明孔)...

我怎样才能用 Python 得到这个?

在我之前处理过的类似图像中,我使用了卷积掩码。基本上我定义了一些我想删除的简单模式的内核:

  kernels = [
             np.array([[1, 0, 1], [1, 0, 1], [1, 0, 1]]),   # vertical line
             np.array([[1, 1, 1], [0, 0, 0], [1, 1, 1]]),   # horizontal line
             np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]]),   # isolated hole
             np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]])    # isolated point
             ]

并应用卷积:

 def match_kernel(matrix, kernel):
     return convolve2d(matrix, kernel, mode='same') + \
         convolve2d(1 - matrix, 1 - kernel, mode='same') == 9

 for kernel in kernels:
     mask += match_kernel(img[:,:,3]/255, kernel)

这会产生一个带有 1 的掩码,其中内核已匹配。现在,我基本上滚动图像来填补这些与邻居之间的空白。

img = np.where((mask == 1)[:,:,None], np.roll(img, 1, axis = 1), img)

问题在于,要以这种方式修复此图像,我需要手动定义许多微调过的内核,这是一个无休止的过程(最终会很慢)。我需要以某种方式概括“洞”的概念。或者更明智的是,使用我不知道的完全不同的方法。

【问题讨论】:

  • 到目前为止你尝试过什么?请问完成后会怎样? (只需用 Photoshop 或 GIMP 模拟)
  • 公平点。我已添加您要求的内容。
  • 也许你可以通过改进删除文本的方法来完全避免这个问题。
  • 原图非常相似(我也附在问题上)。文本由灰色像素组成,带有令人讨厌的阴影,该阴影只是相同的图案移动并变得透明。

标签: python image-processing


【解决方案1】:

间隙填充是一个经典的形态学问题。试试这个:

import cv2
import numpy as np

img = cv2.imread("C:\\Test\\input.png")

# Choose the maximum hole size, in this case 5 x 5
kernel = np.ones((5, 5), np.uint8)

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

cv2.imshow("Gaps Filled", closing)

cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

编辑:如果您需要使用二进制结果作为掩码,请使用以下内容

import cv2
import numpy as np

img = cv2.imread("C:\\Test\\input.png")

# Choose the maximum hole size, in this case 5 x 5
kernel = np.ones((5, 5), np.uint8)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh, bw_img = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
closing = cv2.morphologyEx(bw_img, cv2.MORPH_CLOSE, kernel)

cv2.imshow("Thresholded", bw_img)
cv2.imshow("Gaps Filled", closing)

cv2.waitKey(0)
cv2.destroyAllWindows()

【讨论】:

  • 感谢您的提示。这绝对是要走的路。尽管使用了 scikit-image 和形态学关闭,但我自己也遇到了类似的解决方案。我打算提供一个答案,不要让这个问题悬而未决,但我认为你的很好,所以我会接受它,因为它对未来的读者有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
  • 2011-08-06
相关资源
最近更新 更多