2012-11-27 9 views
6

Chcę wyodrębnić sylwetkę obrazu i próbuję to zrobić za pomocą funkcji konturu MatplotLib. To jest mój kod:Wyodrębnij zewnętrzny kontur lub sylwetkę obrazu w Pythonie

from PIL import Image 
from pylab import * 

# read image to array 
im = array(Image.open('HOJA.jpg').convert('L')) 

# create a new figure 
figure() 

# show contours with origin upper left corner 
contour(im, origin='image') 
axis('equal') 

show() 

To jest mój oryginalny obraz:

Original

I to jest mój wynik:

Contour

Ale ja po prostu chcę pokazać zewnętrzny kontur, sylwetka. Tylko linie odczytu w tym przykładzie.

Jak mogę to zrobić? Przeczytałem dokumentację funkcji contour, ale nie mogę uzyskać tego, czego chcę.

Jeśli znasz lepszy sposób na zrobienie tego w Pythonie, proszę powiedz mi! (MatplotLib, OpenCV, itp.)

Odpowiedz

12

Jeśli chcesz trzymać się konturu, możesz po prostu dodać argument poziomu z wartością "progującą" obraz pomiędzy białym tłem a liściem.

Można użyć histogramu, aby znaleźć odpowiednią wartość. Ale w tym przypadku zrobi to każda wartość nieco niższa niż 255.

Więc:

contour(im, levels=[245], colors='black', origin='image') 

enter image description here

Upewnij kasy Scikit-Image, jeśli chcesz zrobić jakąś poważną przetwarzania obrazu. Zawiera on kilka algoritms wykrywania krawędzi itp

http://scikit-image.org/docs/dev/auto_examples/

+0

Świetna odpowiedź! I dziękuję za radę na temat Scikit-Image, sprawdzę to! – Xithias

0

Chciałbym polecić za pomocą OpenCV na wydajność. Ma funkcje findContour dostępne z Pythona za pomocą wiązania cv2. Ta funkcja może być ustawiona tak, aby zwracać tylko kontur zewnętrzny.

Będziesz także musiał progować swój obraz.

+0

Czy mógłbyś opublikować kod do wyodrębniania zewnętrznego konturu za pomocą OpenCV? – Xithias

+0

Już miałem odpowiedzieć. Wydaje się za późno! –

4

Dla tych, którzy chcą rozwiązania OpenCV, tutaj jest:

ret,thresh = cv2.threshold(image,245,255,0) 
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 

tam = 0 

for contorno in contours: 
    if len(contorno) > tam: 
     contornoGrande = contorno 
     tam = len(contorno) 

cv2.drawContours(image,contornoGrande.astype('int'),-1,(0,255,0),2) 

cv2.imshow('My image',image) 

cv2.waitKey() 
cv2.destroyAllWindows() 

W tym przykładzie, tylko wyciągnąć największy kontur. Pamiętaj, że "obraz" musi być tablicą jednokanałową.

Powinieneś zmienić parametry funkcji progowej, funkcji findContours i funkcji drawContours, aby uzyskać to, co chcesz.

zrobić konwersję do 'int' w funkcji drawContours bo tam jest błąd w Open CV 2.4.3 wersja, a jeśli tego nie zrobisz, program się zepsuje. This is the bug.

Powiązane problemy