
我必须探测到离地面很近的物体。它的大部分区域在灰度上与路面相似,但在视觉上有一个合适的形状。我尝试了手动阈值,图像填充和轮廓。但是没有好的结果。轮廓是最差的。我的目标是得到一个物体为前景(白色)的二值图像。
发布于 2019-01-20 20:43:42
这是一张小图片:p
这就是我解决你的问题的方法:首先,我检测图像中的边缘。接下来,我使用morphological closing将紧密相连的行连接在一起。这在外边,形状的轮廓上工作得很好。然后可以检测该形状的轮廓(cv2.RETR_EXTERNAL仅返回最外轮廓)。由于一些噪声,我添加了一个大小阈值,并在新图像上绘制填充剩余的轮廓。
我添加了第二个选项,它更高效,但可能不适用于项目的其余部分,因为它对其他图像的灵活性较差。在这里,边缘被获取并完成了一个大的形态闭合,这将整个形状连接在一起。为了消除噪声,然后执行较小的形态学开口。正如您在下面看到的,结果几乎相同,尽管其他图像的差异可能更大。
最后注意:如果这个蒙版太粗糙,你可以使用这个蒙版来剪切图像的相关区域,然后用它来创建一个更好的蒙版。
结果:

代码:
import numpy as np
import cv2
# load image
image = cv2.imread("image.png")
# detect edges in image
edges = cv2.Canny(image,100,100)
#option 1: use contours
# solidify / join edges
kernel = np.ones((10,10),np.uint8)
mask = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
# create black image with the size of image
result = np.zeros(image.shape[:2])
# detect contours in the mask (outer edges only)
im, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# draw contour
for cnt in contours:
if cv2.contourArea(cnt) > 100:
# draw filled contour in white on result
cv2.drawContours(result, [cnt], 0, (255), -1)
# draw outline of contour in red on original image
cv2.drawContours(image, [cnt], 0, (0,0,255), 2)
#option 2: morphology only
# solidify / join edges
kernel2 = np.ones((20,20),np.uint8)
mask2 = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel2)
# remove noise
kernel3 = np.ones((5,5),np.uint8)
result2 = cv2.morphologyEx(mask2, cv2.MORPH_OPEN, kernel3)
# show image and results
cv2.imshow("image", image)
cv2.imshow("edges", edges)
cv2.imshow("Result_option1", result)
cv2.imshow("Result_option2", result2)
# release recourses
cv2.waitKey(0)
cv2.destroyAllWindows()https://stackoverflow.com/questions/54266354
复制相似问题