我正在python中使用openCV来检测混凝土中的裂缝。我能够使用Canny边缘检测来检测裂纹。接下来,我需要填充边缘。我使用了openCV的Floodfill操作,但是有些空白被填补了,而有些空白没有填补。左侧的image是输入图像,而右侧的是image。我猜这是因为我的边缘有些断点。我该如何解决? 我的洪水代码:
im_th1 = imginput
im_floodfill = im_th1.copy()
# Mask used to flood filling.
# Notice the size needs to be 2 pixels than the image.
h, w = im_th1.shape[:2]
mask = np.zeros((h + 2, w + 2), np.uint8)
# Floodfill from point (0, 0)
cv2.floodFill(im_floodfill, mask, (5, 5), 255);
# Invert floodfilled image
im_floodfill_inv = cv2.bitwise_not(im_floodfill)
# Combine the two images to get the foreground.
im_out = im_th1 | im_floodfill_inv
cv2.imshow("Foreground", im_out)
cv2.waitKey(0)
答案 0 :(得分:0)
我在SO上经常看到这种情况,每个人都想使用边缘检测,然后填充边缘之间的区域。
除非您使用一种有目的地创建闭合轮廓的边缘检测方法,否则检测到的边缘可能不会形成闭合轮廓。除非具有封闭的轮廓,否则无法填充区域。
在大多数情况下,只需进行一些过滤和简单的阈值即可。例如:
import PyDIP as dip
import matplotlib.pyplot as pp
img = dip.Image(pp.imread('oJAo7.jpg')).TensorElement(1) # From OP's other question
img = img[4:698,6:]
lines = dip.Tophat(img, 10, polarity='black')
dip.SetBorder(lines, [0], [2])
lines = dip.PathOpening(lines, length=100, polarity='opening', mode={'robust'})
lines = dip.Threshold(lines, method='otsu')[0]
这个结果是在一个简单的礼帽式过滤器之后获得的,该过滤器仅保留薄的东西,然后打开路径,仅保留长的东西。这种组合消除了大型阴影以及小的颠簸和物体。过滤后,一个简单的Otsu阈值将生成一个二进制图像,该图像标记裂缝中的所有像素。
注意:
答案 1 :(得分:0)
我找到了想要的解决方案。将其发布在这里,因为它可能会被其他人使用。经过互联网上的一些研究,这里仅显示了两行代码:How to complete/close a contour in python opencv?
对我有用的代码是:
return_hello()
结果在image附件中,显示在结果之前和之后。