2014-10-01 277 views
0

我试图在openCV中使用Canny过滤器来识别轮廓并填充轮廓以创建一个蒙版。我有这样的起始图像: preprocessed image在opencv中填充轮廓

我试图找出我的图像中的所有功能,绘制轮廓,并填充它们。我想这个代码在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() 

回答

1

你所说的 “识别轮廓” 和 “识别的所有功能” 是什么意思?如果您只需要明亮图像部分的蒙版,则不需要查找轮廓,然后填充它们以显示此类图像,只需使用任何类型的阈值即可获得所需的二元蒙版。

+0

'特征'在这里指图像中的浅色点。 'Countours'指的是这些点上的边缘。由于采用了一些自动阈值算法,二进制滤波在过去使用ImageJ是不可靠的,但它是一种有效的选择。我想比较这两种方法。 – JMarotta 2014-10-01 18:32:56

+0

OP用二进制掩码结果更新。 – JMarotta 2014-10-01 18:57:10

0

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

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

所以,我将关闭的问题。

2

如果你想使之更加独立或更少的参数,我建议以下的管道: -

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

我会研究它。谢谢! – JMarotta 2014-10-20 18:49:11