2016-03-30 5 views
4

Я выяснил, как обнаружить края изображения с помощью PIL (изображения будут в основном белым фоном с черными метками). Как я могу определить прямоугольник, который охватывает эти края, чтобы я мог обрезать изображение.Python: Обнаружение прямоугольника в изображении и обрезание его на площади?

Например, я хотел бы, чтобы обрезать что-то вроде этого:

enter image description here

в:

enter image description here

или это:

enter image description here

в:

enter image description here

Я знаком с кадрирование в PIL, за исключением я не знаю, как автоцентр вокруг объекта.

Update:

мне удалось обнаружить края, выполнив следующие действия:

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

Как бы я получить прямоугольник, содержащий все эти края?

enter image description here

+0

Ooh, что должно быть довольно сложно. Откуда вы знаете, где эта «ключевая особенность»? Это интересно, хотя – ForceBru

+0

Ой с помощью ключевой функции я имел в виду любые отметки (в приведенном выше примере это всего 3), она попыталась бы обрезать ее так, чтобы все метки вписывались в новое обрезанное изображение. – KingPolygon

ответ

2

Вы можете сделать это с 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) 

Пример вывода enter image description here

+0

Я еще не установил opencv (возникли проблемы), но было бы неплохо, если бы вы могли прокомментировать свой код :) Я постараюсь проверить его в ближайшее время. – KingPolygon

+0

Открывает ли openCV ширину и высоту прямоугольников или правую и нижнюю координаты с помощью th boundingRect? если это ширина и высота, а не координаты, код выше не будет работать - очень сломанным способом. Если это координаты, вы можете назвать их x1, y1, x2, y2 вместо x, y, w, h. – jsbueno

+0

@jsbueno 'boundingRect' возвращает верхние левые угловые координаты и прямоугольную ширину и высоту. Почему это не работает? – vitalii

Смежные вопросы