Ответ 1
В вашем вопросе неясно, хотите ли вы на самом деле обрезать информацию, определенную в контуре, или замаскировать информацию, которая не имеет отношения к выбранному контуру. Я выясню, что делать в обеих ситуациях.
Маскировка информации
Предполагая, что вы запустили cv2.findContours
на своем изображении, вы получите структуру, в которой перечислены все контуры, доступные на вашем изображении. Я также предполагаю, что вы знаете индекс контура, который использовался для окружения объекта, который вы хотите. Предполагая, что это сохранено в idx
, сначала используйте cv2.drawContours
, чтобы нарисовать заполненную версию этого контура на пустом изображении, а затем используйте это изображение, чтобы проиндексировать его, чтобы извлечь вне объекта. Эта логика маскирует любую нерелевантную информацию и сохраняет только то, что важно - что определено в выбранном вами контуре. Код для этого выглядел бы примерно следующим образом, предполагая, что ваше изображение - это изображение в градациях серого, хранящееся в img
:
import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
# contours, _ = cv2.findContours(...) # Your call to find the contours using OpenCV 2.4.x
_, contours, _ = cv2.findContours(...) # Your call to find the contours
idx = ... # The index of the contour that surrounds your object
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = img[mask == 255]
# Show the output image
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
Если вы действительно хотите обрезать...
Если вы хотите обрезать изображение, вам нужно определить минимальный ограничивающий ограничивающий прямоangularьник области, определенной контуром. Вы можете найти верхний левый и нижний правый angular ограничительной рамки, а затем использовать индексирование, чтобы вырезать то, что вам нужно. Код будет таким же, как и раньше, но будет дополнительный шаг обрезки:
import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
# contours, _ = cv2.findContours(...) # Your call to find the contours using OpenCV 2.4.x
_, contours, _ = cv2.findContours(...) # Your call to find the contours
idx = ... # The index of the contour that surrounds your object
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = img[mask == 255]
# Now crop
(y, x) = np.where(mask == 255)
(topy, topx) = (np.min(y), np.min(x))
(bottomy, bottomx) = (np.max(y), np.max(x))
out = out[topy:bottomy+1, topx:bottomx+1]
# Show the output image
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
Код обрезки работает так, что когда мы определяем маску для выделения области, определенной контуром, мы дополнительно находим наименьшие горизонтальные и вертикальные координаты, которые определяют левый верхний angular контура. Мы также находим самые большие горизонтальные и вертикальные координаты, которые определяют левый нижний angular контура. Затем мы используем индексирование с этими координатами, чтобы обрезать то, что нам действительно нужно. Обратите внимание, что выполняется обрезка маскированного изображения - это изображение, которое удаляет все, кроме информации, содержащейся в самом большом контуре.
Заметка с OpenCV 3.x
Следует отметить, что приведенный выше код предполагает, что вы используете OpenCV 2.4.x. Обратите внимание, что в OpenCV 3.x определение cv2.drawContours
изменилось. В частности, выходные данные представляют собой трехэлементный кортеж, в котором первое изображение является исходным, а два других параметра такие же, как в OpenCV 2.4.x. Поэтому просто измените оператор cv2.findContours
в приведенном выше коде, чтобы игнорировать первый вывод:
_, contours, _ = cv2.findContours(...) # Your call to find contours