2012-11-27 12 views
6

Ich möchte die Silhouette eines Bildes extrahieren, und ich versuche, es zu tun mit der Konturfunktion von matplotlib. Dies ist mein Code:in Python

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() 

Dieses ist mein ursprüngliches Bild:

Original

Und das ist mein Ergebnis:

Contour

Aber ich will nur die äußere zeigen Kontur, die Silhouette. Nur die Leselinien in diesem Beispiel.

Wie kann ich es tun? Ich lese die Dokumentation der contour Funktion, aber ich kann nicht bekommen, was ich will.

Wenn Sie eine bessere Art und Weise wissen, dass dies in Python zu tun, erklären Sie mir bitte! (MatplotLib, OpenCV, etc.)

Antwort

12

Wenn Sie mit Ihrem Konturansatz bleiben möchten, können Sie einfach ein Ebenenargument mit einem Wert hinzufügen, der das Bild zwischen dem weißen Hintergrund und dem Blatt "schwankt".

Sie könnten das Histogramm verwenden, um einen entsprechenden Wert zu finden. Aber in diesem Fall wird jeder Wert etwas niedriger als 255 tun. So

:

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

enter image description here

Stellen Sie sicher, Sie Prüfung Scikit-Bild, wenn Sie einige ernsthafte Bildverarbeitung tun möchten. Es enthält mehrere Kantenerkennung Algorithmen, usw.

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

+0

Große Antwort! Und danke für deinen Rat zu Scikit-Image, ich werde es dir anschauen! – Xithias

0

I würde OpenCV empfehlen für die Leistung verwendet wird. Es hat eine findContour Funktionen zugänglich von Python der cv2 Bindung verwenden. Diese Funktion kann so eingestellt werden, dass nur die externe Kontur zurückgegeben wird.

Sie werden auch mit den Schwellen Ihr Bild haben.

+0

Können Sie den Code zum Extrahieren der externen Kontur mit OpenCV eingeben? – Xithias

+0

Ich war im Begriff, dir zu antworten. Zu spät es scheint! –

4

Für diejenigen, die OpenCV Lösung wollen, hier ist es:

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() 

In diesem Beispiel habe ich die größte Kontur nur zeichnen. Denken Sie daran, dass "Bild" ein Einkanal-Array sein muss.

Sie sollten die Parameter der Schwellenfunktion ändern, die findContours Funktion und die drawContours funktionieren zu bekommen, was Sie wollen.

ich tun, um die Umstellung auf 'int' in der drawContours Funktion, weil es einen Fehler in Open CV 2.4 ist.3 Version, und wenn Sie diese Konvertierung nicht machen, bricht das Programm. This is the bug.