使用哪种算法来分割与背景类似的灰度对象? [英] Which algorithm to use to segment out an object with grayscale similar to background?

查看:85
本文介绍了使用哪种算法来分割与背景类似的灰度对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to detect an object very close to ground. It has most area similar to road surface in terms of grey scale, but visually it has a proper shape. I tried with manual thresholding, image filling and contours. But no good results. Contours are worst. My aim is to get a binary image with the object as foreground (white).

推荐答案

那是一个小图像:p

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

This is how I approached your problem: first I detected the edges in the image. Next I used morphological closing to join lines that are close together. This works very well on the outer edges, the outline of the shape. Then the contour of this shape could be detected (cv2.RETR_EXTERNAL returns only the outermost contour). Because of some noise I added a size threshold, and the remaining contour is drawn filled on a new image.

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

I added a second option, that is more efficient, but might not work for the rest of your project, because it is less flexible for other images. Here the edges are taken and a large morphological closing is done, which joins together the entire shape. To remove the noise a smaller morphological opening is then performed. As you can see below, the results are nearly identical, though the difference may be bigger for other images.

最后一点:如果此蒙版太粗糙,则可以使用该蒙版切出图像的相关区域,然后使用它来创建更好的蒙版.

Final note: if this mask is too crude, you can use the mask to cut out the relevant area of your image and use this to create a better mask.

结果:

代码:

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

这篇关于使用哪种算法来分割与背景类似的灰度对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆