在opencv中填充轮廓

时间:2014-10-01 16:12:56

标签: python opencv

我尝试使用openCV中的Canny过滤器识别轮廓并填充轮廓,以便创建蒙版。我有这种起始形象: preprocessed image

我试图识别图像中的所有特征,绘制轮廓并填充它们。我试图在openCV中使用此代码实现它:

img = cv2.imread(os.path.join(fName,f), 0)  
img = cv2.GaussianBlur(img,(5,5),0)
cv2.bilateralFilter(img, 9, 150,450)
edge = np.zeros((img.shape[0] + 2, img.shape[1] + 2), np.uint8)
edge = cv2.Canny(img, 500, 300, apertureSize=5)
cont, heir = cv2.findContours(edge.copy(), cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
contours = [cv2.approxPolyDP(cnt, 3, True) for cnt in cont]
cv2.morphologyEx(img, cv2.MORPH_CLOSE, np.ones((5,5), dtype='uint8'))
cv2.drawContours(img, contours, -1, 255, -1)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis

大多数情况下,我猜测参数(反复试验;这很难!)。不幸的是,我没有用白色填充整齐的轮廓,而是得到更像这样的东西:image with edges detected

有什么想法吗?显然,我需要更好地关闭边缘,并调整我的一些Canny参数,但我确实可以使用一些指导。

谢谢!

编辑:阈值处理并没有很好地创建我想要的那种面具,或者是:Binary Thresholding我认为我的光明'点不是比背景亮得多,但我希望能够在黑色背景上有白点。

代码:

    img = cv2.imread(os.path.join(fName,f), 0)
    cv2.bilateralFilter(img, 9, 90,16)
    #img = cv2.GaussianBlur(img,(5,5),0)
    #binImg = np.zeros((img.shape[0], img.shape[1]), np.uint8)   
    binImg = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,           cv2.THRESH_BINARY, 25, 2)
    #binImg = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    #newimg = np.multiply(img, np.divide(edge, 255.0))    
    plt.imshow(binImg, cmap = 'gray', interpolation = 'bicubic')
    plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
    #plt.show()  

4 个答案:

答案 0 :(得分:2)

如果你想让它或多或少与参数无关,我会建议以下管道: -

  1. 做一个超像素分段。我建议:https://github.com/PSMM/SLIC-Superpixels
  2. 对于每个超像素,计算平均亮度/强度。
  3. 阈值(自动或某种巧妙的方式)来获得明亮的超像素。
  4. 相应地创建面具

答案 1 :(得分:1)

你是什么意思"识别轮廓"和"识别所有功能"?如果你只需要明亮的图像部分的掩模,你不需要找到轮廓,然后填写它们显示的这种图像,只需使用任何类型的阈值,你将有所需的二进制掩码。

答案 2 :(得分:1)

对于它的价值,二元面具是更好的方法。谢谢你的建议。它只是意味着玩一些参数。对于这些功能,我发现了以下代码:

img = cv2.imread(os.path.join(fName,f), 0)
cv2.bilateralFilter(img, 9, 90,16)
img = cv2.GaussianBlur(img,(5,5),0)
#binImg = np.zeros((img.shape[0], img.shape[1]), np.uint8)   
binImg = cv2.adaptiveThreshold(img, 1, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 55, -3)
#cv2.bilateralFilter(binImg, 9, 90,16)
#binImg = cv2.GaussianBlur(binImg, (3,3), 0)
#ret, binImg = cv2.threshold(img, 35000, 1, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
plt.imshow(binImg, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis

产生我正在寻找的那种面具: Successful

所以,我要解决这个问题。

答案 3 :(得分:0)

您可以尝试FloodFill()。请记住包括

#include    <opencv2/imgproc.hpp>