too - Obtener el área dentro de los contornos Opencv Python?
opencv detect rectangle (1)
He utilizado una técnica de umbralización adaptativa para crear una imagen como la siguiente:
El código que utilicé fue:
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)
Entonces, uso este código para obtener contornos:
cnt = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
Mi objetivo es generar una máscara usando todos los píxeles dentro del contorno exterior, así que quiero completar todos los píxeles dentro del objeto para que sean blancos. ¿Cómo puedo hacer esto?
He intentado el código siguiente para crear una máscara, pero la máscara resultante parece no ser diferente de la imagen después de aplicar el umbral de adaptación
mask = np.zeros(image.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)
Lo que tienes es casi correcto. Si echas un vistazo a tu imagen con umbral, la razón por la que no funciona es porque el objeto de tu zapato tiene espacios en la imagen. Específicamente, lo que busca es que espere que el zapato tenga su perímetro para estar todo conectado. Si esto sucediera, entonces si extraes el contorno más externo (que es lo que está haciendo tu código), solo deberías tener un contorno que represente el perímetro exterior del objeto. Una vez que complete el contorno, entonces su zapato debe ser completamente sólido.
Debido a que el perímetro de su zapato no está completo y roto, esto da como resultado regiones blancas desconectadas. Si usa findContours
para encontrar todos los contornos, solo encontrará los contornos de cada una de las formas blancas y no del perímetro más externo. Como tal, si intentas usar findContours
, te dará el mismo resultado que la imagen original, porque simplemente estás buscando el perímetro de cada región blanca dentro de la imagen, y luego findContours
estas regiones con findContours
.
Lo que debe hacer es asegurarse de que la imagen esté completamente cerrada. Lo que recomendaría es hacer uso de la morfología para cerrar todas las regiones desconectadas, luego ejecutar una llamada a findContours
en esta nueva imagen. Específicamente, realice un cierre morfológico binario. Lo que hace es que toma regiones blancas desconectadas que están muy juntas y garantiza que estén conectadas. Use un cierre morfológico, y tal vez use algo así como un elemento de estructura cuadrada de 7 x 7 para cerrar el zapato. Este elemento de estructuración se puede considerar como la separación mínima entre las regiones blancas para considerarlas como conectadas.
Como tal, haz algo como esto:
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)
Este código toma esencialmente su imagen de umbral y aplica un cierre morfológico a esta imagen. Después, encontramos los contornos externos de esta imagen y los rellenamos con blanco. FWIW, descargué su imagen de umbral y probé esto por mi cuenta. Esto es lo que obtengo con tu imagen: