我必须检测到非常靠近地面的物体。就灰度而言,它的大部分区域与路面相似,但在视觉上具有适当的形状。我尝试了手动阈值,图像填充和轮廓。但是没有好结果。轮廓最差。我的目标是获取一个以对象为前景的二进制图像(白色)。
答案 0 :(得分:0)
那是一个小图像: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()