使用哪种算法来分割与背景类似的灰度对象?

时间:2019-01-19 10:57:36

标签: image matlab opencv image-processing computer-vision

https://i.stack.imgur.com/3seCh.png

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

1 个答案:

答案 0 :(得分:0)

那是一个小图像:p

这就是我解决您的问题的方式:首先,我检测到图像中的边缘。接下来,我使用morphological closing连接在一起的线。这在外边缘(形状的轮廓)上效果很好。然后可以检测到该形状的轮廓(cv2.RETR_EXTERNAL仅返回最外轮廓)。由于一些噪音,我添加了尺寸阈值,然后将其余轮廓绘制为填充在新图像上。

我添加了第二个选项,它效率更高,但可能不适用于项目的其余部分,因为它对其他图像的灵活性较差。在这里取边,完成大的形态封闭,将整个形状连接在一起。为了去除噪声,然后执行较小的形态学开口。如下所示,结果几乎相同,尽管其他图像的差异可能更大。

最后的注意:如果该蒙版太粗糙,则可以使用该蒙版切出图像的相关区域,并使用它来创建更好的蒙版。

结果:

enter image description here

代码:

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()