Получить участок в пределах контуров в формате OpenCV в Python?

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

enter image description here

код, который я использовал:

image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)

затем я использую этот код для получения контуров:

cnt = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]

моя цель-создать маску, используя все пиксели во внешнем контуре,поэтому я хочу заполнить все пиксели в объекте белым. Как я могу это сделать?

Я пробовал код ниже, чтобы создать маску, но в результате маска не отличается от изображения после применения адаптивного порога

mask = np.zeros(image.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)

1 ответов


то, что у вас есть, почти правильно. Если вы посмотрите на свой обмолоченный образ, причина, по которой он не работает, заключается в том, что ваш объект обуви имеет пробелы в изображения. В частности, то, что вам нужно, - это то, что вы ожидаете, что обувь имеет свой периметр все подключен. Если это произойдет, то если вы извлекаете самый внешний контур (что и делает ваш код), у вас должен быть только один контур, который представляет внешний периметр объект. Как только вы заполните контур, ваша обувь должна быть полностью твердой.

поскольку периметр вашей обуви не является полным и сломанным, это приводит к отключенным белым областям. Если вы используете findContours чтобы найти все контуры, он найдет только контуры каждой из белых фигур, а не самый внешний периметр. Таким образом, если вы попытаетесь использовать findContours, это даст вам тот же результат, что и исходное изображение, потому что вы просто найти периметр каждого белая область внутри изображения, а затем заполнение этих областей findContours.


что вам нужно сделать, это убедиться, что изображение полностью закрытые. То, что я бы рекомендовал вам сделать, это использовать морфология чтобы закрыть все отключенные области вместе, затем запустите findContours вызовите это новое изображение. В частности, выполните бинарное морфологическое закрытие. Что это делает, так это то, что он принимает отключенные белые области, которые близки друг к другу и гарантирует, что они связаны. Используйте морфологическое закрытие и, возможно, используйте что-то вроде квадратного структурирующего элемента 7 x 7 для закрытия обуви. Этот структурирующий элемент можно рассматривать как минимальное разделение между белыми областями, чтобы считать их связанными.

таким образом, сделайте что-то вроде этого:

import numpy as np
import cv2 
image = cv2.imread('...') # Load your image in here
# Your code to threshold
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)    

# Perform morphology
se = np.ones((7,7), dtype='uint8')
image_close = cv2.morphologyEx(image, cv2.MORPH_CLOSE, se)

# Your code now applied to the closed image
cnt = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
mask = np.zeros(image.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)

этот код по существу принимает ваше пороговое изображение и применяет морфологическое закрытие к этому изображению. После, мы находим внешнее контуры этого изображения и заполните их белым. FWIW, я загрузил ваше пороговое изображение и попробовал это самостоятельно. Вот что я получаю с вашим изображением:

enter image description here