簡體   English   中英

打開 CV 分水嶺沒有正確分割橢圓對象

[英]Open CV Watershed not segmenting oval objects properly

嘗試創建一種方法來處理圖像以計算不同類型的平板電腦。 以下代碼對圓形對象運行良好,但是橢圓形會產生我無法找到解決方法的問題。

kernel = np.ones((5,5),np.uint8)


image = cv2.imread('sample.jpg')
shifted = cv2.GaussianBlur(image, (15, 15), 1)
shifted = cv2.pyrMeanShiftFiltering(shifted, 21, 51)
shifted = cv2.erode(shifted,kernel,iterations=1)
shifted = cv2.dilate(shifted,kernel,iterations=1)
cv2.imwrite("step1.jpg", shifted)
gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255,
    cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imwrite("step2.jpg", thresh)
thresh = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
cv2.imwrite("step3.jpg", thresh)
thresh = cv2.bitwise_not(thresh)
thresh = cv2.erode(thresh,kernel,iterations=1)
cv2.imwrite("step4.jpg", thresh)
D = ndimage.distance_transform_edt(thresh)
localMax = peak_local_max(D, indices=False, min_distance=10,
    labels=thresh)
markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]

labels = watershed(-D, markers, mask=thresh)
print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))
for label in np.unique(labels):
    if label == 0:
        continue
    mask = np.zeros(gray.shape, dtype="uint8")
    mask[labels == label] = 255
    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
        cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    c = max(cnts, key=cv2.contourArea)
    ((x, y), r) = cv2.minEnclosingCircle(c)
    cv2.circle(image, (int(x), int(y)), int(r), (0, 255, 0), 2)
    cv2.putText(image, "#{}".format(label), (int(x) - 10, int(y)),
        cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
cv2.imwrite("step5.jpg", image)
cv2.waitKey(0)

正在使用的圖像是:

https://imgur.com/a/1U49DeT

過濾后的 Output 得到:

https://imgur.com/a/vXwrWlG

任何有關如何解決此問題的教學點將不勝感激。

我認為有更好的方法來使用分水嶺運算符。

它依賴於良好的漸變,但如果圖像與這張相似,您應該能夠有效地做到這一點。 此外,今天有非常強大的邊緣檢測器,比我在這個演示中使用的要好得多。

import cv2 
import numpy as np
import higra as hg
from skimage.segmentation import relabel_sequential
import matplotlib.pyplot as plt 

def main():                                                                                                                                                                                             
    img_path = "pills.jpg"                                                                                                                                                                              
    img = cv2.imread(img_path)                                                                                                                                                                          
    img = cv2.resize(img, (256, 256))                                                                                                                                                                   
    img = cv2.GaussianBlur(img, (9, 9), 0)                                                                                                                                                              

    edges = cv2.Canny(img, 100, 100)                                                                                                                                                                    

    size = img.shape[:2]                                                                                                                                                                                
    graph = hg.get_4_adjacency_graph(size)                                                                                                                                                              
    edge_weights = hg.weight_graph(graph, edges, hg.WeightFunction.mean)                                                                                                                                

    tree, altitudes = hg.watershed_hierarchy_by_area(graph, edge_weights)                                                                                                                               
    segments = hg.labelisation_horizontal_cut_from_threshold(tree, altitudes, 500)                                                                                                                      
    segments, _, _ = relabel_sequential(segments)                                                                                                                                                       
    print('The number of pills is ', segments.max() - 1)                                                                                                                                                
    plt.imshow(segments)                                                                                                                                                                                
    plt.show()                                                                                                                                                                                          

if __name__ == "__main__":                                                                                                                                                                              
    main()                                                                                                                                                                                              

最初,我調整圖像大小以加快計算速度並應用模糊來減少背景漸變。 我檢測它的邊緣(梯度)並用它作為邊緣權重創建一個圖; 然后我計算按面積排序的分水嶺層次結構並閾值它獲得該級別的連接組件,從中您可以計算段數。

分割結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM