2016-03-30 14 views
1

Ben eşiklenir görüntünün kontur bulma ve böylece gibi çiziyorum eğriyi gösterir:Kontur ziyade listeden alınırken bir eğri daha noktaları gösterir, ama aksi

self.disc_contour = cv2.findContours(self.thresh.copy(), cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)[1] 
cv2.drawContours(self.original_image, self.disc_contour, -1, (0,255,0), 2) 

ve ben kontur olsun istenen şekilde: Ideğişirse

enter image description here

(. dış parça bağlamında konturu iç daireyi göz ardı) Ancak

enter image description here

Ne nedeni olabilir: Aşağıdaki sonucu elde self.disc_contour[0] için drawContour işlevinde?

+0

İkinci parametre, konturların bir listesi olmalıdır - diğer bir deyişle, nokta listeleri listesi. Bence self.disc_contour [0] 'sadece tek bir kontur ve openCV her noktayı ayrı bir eğri olarak ele alıyor gibi görünüyor. Bunun yerine [self.disc_contour [0]] 'ı deneyin. (veya 'self.disc_contour [0: 1]'). –

+0

Sadece fark ettiğim bir başka şey - 'cv2.findContours' bir çift döndürür:' (kontür, hiyerarşi) '. İkinci öğeyi (indeks 1) alırsınız, bu da mantıksaldır, ancak kontur listesi olarak mı ele alırsınız? Oh, ya da belki 2.4.x yerine CV 3.x kullanıyorsunuz? API biraz değişmiş gibi görünüyor. Bunu açıklığa kavuşturmamıza izin verecek bir çalışma örneği ekleyebilir misiniz? –

+0

@ DanMašek, çözümün işe yaradı. Cevap olarak gönderirseniz, kabul edeceğim. Ayrıca, evet, Opencv 3.1 kullanıyorum. Çözümünüzün neden çalıştığını açıklayabilir misiniz? Teşekkürler! –

cevap

1

Not: OpenCV 3.x

özgü cv2.findContours ikinci sonuç hatlarına bir listesidir. cv.drawContours'un ikinci parametresi konturlarının listesi olmalıdır.

Bir kontur, noktaların bir listesi (veya dizisi) olarak gösterilir. Her nokta bir koordinat listesidir. Biz cv2.findContours sonucunu incelemek, nedeni var görüştüğünü

:

import cv2 

src_img = cv2.imread("blob.png") 
gray_img = cv2.cvtColor(src_img, cv2.COLOR_BGR2GRAY) 

contours = cv2.findContours(gray_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)[1] 

print(contours) 

# Choose one:  

# Draw only first contour from the list 
cv2.drawContours(src_img, contours, 0, (0,255,0), 2) 
# Pass only the first contour (v1) 
cv2.drawContours(src_img, [contours[0]], -1, (0,255,0), 2) 
# Pass only the first contour (v2) 
cv2.drawContours(src_img, contours[0:1], -1, (0,255,0), 2) 


cv2.imshow("Contour", src_img) 
cv2.waitKey() 

Numune giriş görüntüsünü:

sadece tek kontur nasıl çizileceğini birden çok yolu vardır noktalar belirgin hale gelir - 4 yuvalama seviyesi vardır.

[ 
    array([ 
     [[ 95, 61]], # Point 0 
     [[ 94, 62]], # Point 1 
     [[ 93, 62]], 
     ... <snip> ... 
     [[ 98, 61]], 
     [[ 97, 61]], 
     [[ 96, 61]] 
    ]) # Contour 0 
] 

bu cevabın başında tanımlarına göre, biz örneğin bu durumda noktalar ek listede sarılı olduğunu görebilirsiniz [[ 98, 61]]. OpenCV bununla doğru bir şekilde ilgileniyor - sanırım bu bir özellik olarak tasarlandı.

Dış listeyi yalnızca ilk eleman olan contours kullanarak kaldırırsak, her noktayı tek bir nokta içeren ayrı bir kontura doğru etkili bir şekilde çeviririz.

array([ 
    [ 
     [ 95, 61] # Point 0 
    ], # Contour 0 
    [ 
     [ 94, 62] # Point 0 
    ], # Contour 1 
    ... and so on 
]) 
+0

'[self.disc_contour [0]] 'dış listeyi kaldırırken koordinatları koruyun bir yolu? Çünkü fark ettim ki, kontur artık çizilmezken, noktalar hala eksik. Bir konturun tüm koordinatlarını alabilmemin bir yolu var mı? –

+0

Kontur değişmeden kalacaktır. Orijinal listenin sadece ilk elemanını içeren yeni bir liste yapar. Bu durumda eleman tek bir konturdur. Bu senaryodaki len (self.disc_contour) nedir? Eğer cv2.drawContours' için üçüncü parametreyi kullanarak çizmek için konturu seçerseniz ne olur? Bazı konturlar çakışıyor mu? Bazı puanları kaçırdığınızı nasıl anladınız? –

+0

Bazı noktaları kaçırdığımı anladım çünkü centroid ile aynı y koordinatı yok, hatta bu konu için x koordinatı var. Ayrıca, '(self.disc_contour)' 1'dir. –

İlgili konular