Encuentra el área en una imagen con Python y OpenCV.
Me gustaría encontrar un área en aproximadamente 1,5K imágenes que todas tengan un formato similar. Todas son escaneos de imágenes pintadas o fotografiadas de personas. Todas incluyen la misma tarjeta de color. La tarjeta de color puede estar colocada en cualquier lado de la imagen (ver imagen de muestra a continuación).
El resultado debe ser una imagen que solo contenga el retrato de la persona.
Soy capaz de encontrar la tarjeta de color con la coincidencia de plantilla de OpenCV:
import cv2
import numpy as np
method = cv2.TM_SQDIFF_NORMED
# Leer las imágenes desde el archivo
img_rgb = cv2.imread('./imgs/test_portrait.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('./portraet_color_card.png', 0)
w, h = template.shape[::-1]
result = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = .97
loc = np.where(result >= threshold)
for pt in zip(*loc[::-1]):
print("Encontrado:", pt)
cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,255,255), 2)
cv2.imwrite('result.png',img_rgb)
Salida:
Encontrado: (17, 303)
Encontrado: (18, 303)
Encontrado: (17, 304)
Encontrado: (18, 304)
Con las coordenadas y las dimensiones de la imagen, puedo determinar si la imagen está a la izquierda o a la derecha, y puedo recortar la imagen. El resultado está lejos de ser perfecto, ya que los bordes siguen presentes.
¿Hay una mejor manera de extraer los retratos de las imágenes? Preferiría trabajar con Python y OpenCV, pero estoy abierto a otras sugerencias sobre cómo resolver este problema para un mayor número de imágenes.
Muestras:
Plantilla:
davy.ai
Una posible solución para extraer los retratos de las imágenes es utilizar algoritmos de detección de rostros. OpenCV tiene un algoritmo de detección de rostros incorporado que se puede utilizar para este propósito. Aquí tienes un ejemplo de código para la detección de rostros utilizando OpenCV:
Ten en cuenta que la detección de rostros no es perfecta y puede omitir algunos rostros o detectar falsos positivos. Sin embargo, podría ser un buen punto de partida para extraer los retratos de las imágenes.
Otro enfoque que se podría utilizar es la segmentación. Un método posible para la segmentación es aplicar un algoritmo de umbralización a la imagen, que separa el primer plano del fondo. Aquí tienes un ejemplo de código para la umbralización utilizando OpenCV:
La umbralización puede funcionar bien si el primer plano y el fondo tienen buen contraste y son relativamente fáciles de separar. Sin embargo, es posible que no funcione bien si hay colores o texturas similares en el primer plano y el fondo. En ese caso, podrían ser necesarios algoritmos de segmentación más avanzados, como la segmentación de instancias o la segmentación semántica.