Я пытаюсь надежно извлечь повернутую ограничивающую рамку контуров. Я хотел бы сделать изображение, найти самый большой контур, получить его повернутую ограничивающую рамку, повернуть изображение, чтобы ограничивающая рамка была вертикальной, и обрезать до нужного размера.
Для демонстрации вот исходное изображение, связанное в следующем коде. Я хотел бы закончить туфлю, повернутую по вертикали и обрезанную до нужного размера. Следующий код из этого ответа, похоже, работает с простыми изображениями, такими как строки opencv и т. Д., Но не с фотографиями.
В конце концов, он повернут и неправильно обрезан:
РЕДАКТИРОВАТЬ: после изменения типа порога на cv2.THRESH_BINARY_INV
теперь он повернут правильно, но обрезается неправильно:
import cv2
import matplotlib.pyplot as plt
import numpy as np
import urllib.request
plot = lambda x: plt.imshow(x, cmap='gray').figure
url = 'https://i.imgur.com/4E8ILuI.jpg'
img_path = 'shoe.jpg'
urllib.request.urlretrieve(url, img_path)
img = cv2.imread(img_path, 0)
plot(img)
threshold_value, thresholded_img = cv2.threshold(
img, 250, 255, cv2.THRESH_BINARY)
_, contours, _ = cv2.findContours(thresholded_img, 1, 1)
contours.sort(key=cv2.contourArea, reverse=True)
shoe_contour = contours[0][:, 0, :]
min_area_rect = cv2.minAreaRect(shoe_contour)
def crop_minAreaRect(img, rect):
# rotate img
angle = rect[2]
rows, cols = img.shape[0], img.shape[1]
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
img_rot = cv2.warpAffine(img, M, (cols, rows))
# rotate bounding box
rect0 = (rect[0], rect[1], 0.0)
box = cv2.boxPoints(rect)
pts = np.int0(cv2.transform(np.array([box]), M))[0]
pts[pts < 0] = 0
# crop
img_crop = img_rot[pts[1][1]:pts[0][1],
pts[1][0]:pts[2][0]]
return img_crop
cropped = crop_minAreaRect(thresholded_img, min_area_rect)
plot(cropped)
Как мне получить правильную обрезку?
NameError: name 'min_area_rect' is not defined
. - person Dan Mašek   schedule 25.07.2017cv2.THRESH_BINARY_INV
. На верхнем уровнеfindContours
ищет белые объекты на черном фоне, поэтому на белом фоне самый большой контур соответствует всему изображению. - person Dan Mašek   schedule 25.07.2017minAreaRect
тоже немного сложно. Для ограничивающего прямоугольника полного изображения я получаю((492.5, 415.5), (829.0, 983.0), -90.0)
- обратите внимание, что он говорит, что он выше, чем шире, с углом -90 градусов. Это необходимо учитывать, иначе он будет вращаться, когда не должен. - person Dan Mašek   schedule 25.07.2017