2016-03-30 31 views
4

Ich habe herausgefunden, wie man Kanten in einem Bild mit PIL erkennt (Bilder sind meistens weißer Hintergrund mit schwarzen Zeichenmarken). Wie kann ich das Rechteck erkennen, das diese Kanten umfasst, damit ich das Bild zuschneiden kann?Python: Kanten von Kanten erkennen und in ein Quadrat zuschneiden?

Zum Beispiel würde Ich mag so etwas beschneiden:

enter image description here

in:

enter image description here

oder dies:

enter image description here

in:

enter image description here

Ich bin mit Zuschneiden in PIL vertraut, außer ich weiß nicht, wie Auto zum Zentrum um ein Objekt.

Update:

Ich habe es geschafft, um die Kanten zu erkennen, indem Sie folgendermaßen vorgehen:

from PIL import Image, ImageFilter 
image = Image.open("myImage.png") 
image = image.filter(ImageFilter.FIND_EDGES) 

Wie würde ich das rect alle diese Kanten enthalten?

enter image description here

+0

Ooh, dass es ziemlich schwierig sein. Woher weißt du, wo dieses "Schlüsselmerkmal" ist? Das ist interessant, aber – ForceBru

+0

Oh nach Schlüsselmerkmal meinte ich irgendwelche Markierungen (im Beispiel oben ist es die ganze Zahl 3), es würde versuchen, es zu beschneiden, so dass alle Markierungen in das neue zugeschnittene Bild passen. – KingPolygon

Antwort

2

Sie es tun können, beispiels mit opencv

import cv2 

#Load the image in black and white (0 - b/w, 1 - color). 
img = cv2.imread('input.png', 0) 

#Get the height and width of the image. 
h, w = img.shape[:2] 

#Invert the image to be white on black for compatibility with findContours function. 
imgray = 255 - img 
#Binarize the image and call it thresh. 
ret, thresh = cv2.threshold(imgray, 127, 255, cv2.THRESH_BINARY) 

#Find all the contours in thresh. In your case the 3 and the additional strike 
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 
#Calculate bounding rectangles for each contour. 
rects = [cv2.boundingRect(cnt) for cnt in contours] 

#Calculate the combined bounding rectangle points. 
top_x = min([x for (x, y, w, h) in rects]) 
top_y = min([y for (x, y, w, h) in rects]) 
bottom_x = max([x+w for (x, y, w, h) in rects]) 
bottom_y = max([y+h for (x, y, w, h) in rects]) 

#Draw the rectangle on the image 
out = cv2.rectangle(img, (top_x, top_y), (bottom_x, bottom_y), (0, 255, 0), 2) 
#Save it as out.jpg 
cv2.imwrite('out.jpg', img) 

Beispiel Ausgabe enter image description here

+0

Ich habe opencv noch nicht installiert (Probleme), aber es wäre nett, wenn Sie Ihren Code kommentieren könnten :) Ich werde versuchen, es bald auszuprobieren. – KingPolygon

+0

Liefert openCV Breite und Höhe von Rechtecken oder rechten und unteren Koordinaten mit dem Aufruf von boundingRect? Wenn es sich um Breite und Höhe und nicht um Koordinaten handelt, funktioniert der obige Code nicht - auf sehr kaputte Weise. Wenn es sich um Koordinaten handelt, könnten Sie sie anstelle von x, y, w, h als x1, y1, x2, y2 bezeichnen. – jsbueno

+0

@jsbueno 'boundingRect' gibt die Koordinaten der oberen linken Ecke und die rect Breite und Höhe zurück. Warum funktioniert es nicht? – vitalii