由于删除了一些写在原始图像上的字母,我的图像有相对较小的孔。还有其他有意义的洞,我不想碰它们。我想“检测并填充相邻的颜色”这些小工件。这是我拥有的示例图像(请注意,这里的白色并不是真正的白色,而是透明的),在我想要得到的结果下方:
此外,我附上原始图像的快照和文本(以防有人发现从这一点开始处理图像更容易,而不是我上面描述的透明孔)...
我怎样才能用 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)
问题是要以这种方式修复此图像,我需要手动定义许多微调的内核,这是一个无休止的过程(最终会很慢)。我需要以某种方式概括“洞”的概念。或者也许更明智的是,使用一种我不知道的完全不同的方法。
答案 0 :(得分:0)
间隙填充是一个经典的形态学问题。试试这个:
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()