2014-10-01 182 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