👨 Detectar rostros con modelos pre-entrenados con DNN de OpenCV | Python

Por Administrador

En este tutorial veremos como usar un modelo pre entrenado con aprendizaje profundo para la detección de rostros con OpenCV, para lo cual usaremos el módulo dnn, así que ¡vamos a por ello!.

CONTENIDO

  • Detección de rostros con dnn de OpenCV
    • Instalación de packages
    • Descargar la arquitectura y pesos del modelo para detectar rostros con dnn
    • ¡Vamos con la programación!
    • Referencias

Detección de rostros con dnn de OpenCV

En este blog como en mi canal, ya tenemos un par de videos sobre detección facial como:

En los cuales se busca detectar el rostro de una persona en una imagen. Como podrás darte cuenta, podrías escoger alguno de estos u otros (puesto que se encuentran muchos detectores de rostros disponibles en repositorios), pero ¿cómo escoger alguno?.

Pues bien, esto dependerá de la aplicación que desees realizar, es decir, si trabajas en imágenes con buenas condiciones en el entorno, podrías tranquilamente usar el detector de rostros de haar cascades de OpenCV. Sin embargo, si tu proyecto se aplica sobre imágenes cuyo entorno no es tan controlado, es decir, donde exista poca iluminación, desorden en el fondo y los rostros de las personas no se muestren muy al frente a la cámara, puede que tengas que usar otro detector de rostros más preciso, como el que veremos hoy.

Puede que también te encuentres con que necesites buena precisión, pero que el detector no sea tan pesado computacionalmente. En fin, existen un montón de variables a la hora de escoger un detector facial, por ello entre más opciones mejor.

En esta ocasión veremos como usar Dnn de OpenCV para cargar un modelo pre entrenado que nos ayudará a detectar rostros con muy buena precisión en imágenes o videos. Para conseguirlo, en primer lugar tendremos que instalar OpenCV y luego tendremos que descargar la arquitectura y los pesos ya entrenados por terceros.

Instalación de packages

Vamos a instalar OpenCV con pip install opencv-contrib-python. Si digitamos pip freeze podremos ver todos los paquetes instalados.

Figura 1: Lista de los módulos instalados.

Te preguntarás, ¿de dónde sale Numpy, si no lo habíamos instalado?. Pues bien, al momento de instalar OpenCV, también se instala Numpy.

IMPORTANTE: Hay que tomar en cuenta que para el uso del módulo dnn, debemos contar con versiones igual o superiores a OpenCV 3.3. 

Descargar arquitectura y pesos del modelo para detectar rostros con dnn

En primer lugar, vamos a descargar la arquitectura de la red, para ello nos dirigimos a este link, elegimos deploy.prototxt, y lo descargamos. 

Para los pesos del modelo, vamos a dirigirnos a este link, escogemos res10_300x300_ssd_iter_140000.caffemodel y lo descargamos.

NOTA: En el videotutorial podrás encontrar de forma más detallada los pasos a seguir para descargar los archivos.

¡Vamos con la programación!

Para una explicación más detallada del programa que veremos a continuación, por favor dirígete al video que he preparado en mi canal, en donde explico paso a pasito cada procedimiento efectuado. ¡Anímate a verlo 😉!.

El primer programa lo podrás probar con imágenes, solo tendrás que cambiar el path del modelo y de las imágenes de entrada. Así que siéntete libre de experimentar con este detector:

import cv2

# ------------ READ DNN MODEL ------------
# Model architecture
prototxt = "model/deploy.prototxt"
# Weights
model = "model/res10_300x300_ssd_iter_140000.caffemodel"

# Load the model
net = cv2.dnn.readNetFromCaffe(prototxt, model)

# ------- READ THE IMAGE AND PREPROCESSING -------
image = cv2.imread("Images_videos/imagen_0001.jpg")
height, width, _ = image.shape
image_resized = cv2.resize(image, (300, 300))

# Create a blob
blob = cv2.dnn.blobFromImage(image_resized, 1.0, (300, 300), (104, 117, 123))
print("blob.shape: ", blob.shape)
blob_to_show = cv2.merge([blob[0][0], blob[0][1], blob[0][2]])

# ------- DETECTIONS AND PREDICTIONS ----------
net.setInput(blob)
detections = net.forward()
print("detections.shape:", detections.shape)

for detection in detections[0][0]:
     print("detection:", detection)
     if detection[2] > 0.5:
          box = detection[3:7] * [width, height, width, height]
          x_start, y_start, x_end, y_end = int(box[0]), int(box[1]), int(box[2]), int(box[3])
          cv2.rectangle(image, (x_start, y_start), (x_end, y_end), (0, 255, 0), 2)
          cv2.putText(image, "Conf: {:.2f}".format(detection[2] * 100), (x_start, y_start - 5), 1, 1.2, (0, 255, 255), 2)

cv2.imshow("Image", image)
#cv2.imshow("blob_to_show", blob_to_show)
cv2.waitKey(0)
cv2.destroyAllWindows()

En cambio, este es el programa en donde podrás probar la detección facial en video:

import cv2

# ------------ READ DNN MODEL ------------
# Model architecture
prototxt = "model/deploy.prototxt"
# Weights
model = "model/res10_300x300_ssd_iter_140000.caffemodel"

# Load the model
net = cv2.dnn.readNetFromCaffe(prototxt, model)

# ------- READ THE IMAGE AND PREPROCESSING -------
cap = cv2.VideoCapture("Images_videos/video_001.mp4")

while True:
     ret, frame = cap.read()
     if ret == False:
          break

     height, width, _ = frame.shape
     frame_resized = cv2.resize(frame, (300, 300))

     # Create a blob
     blob = cv2.dnn.blobFromImage(frame_resized, 1.0, (300, 300), (104, 117, 123))

     # ------- DETECTIONS AND PREDICTIONS ----------
     net.setInput(blob)
     detections = net.forward()
     #print("detections.shape:", detections.shape)

     for detection in detections[0][0]:
          #print("detection:", detection)
          if detection[2] > 0.5:
               box = detection[3:7] * [width, height, width, height]
               x_start, y_start, x_end, y_end = int(box[0]), int(box[1]), int(box[2]), int(box[3])
               cv2.rectangle(frame, (x_start, y_start), (x_end, y_end), (0, 255, 0), 2)
               cv2.putText(frame, "Conf: {:.2f}".format(detection[2] * 100), (x_start, y_start - 5), 1, 1.2, (0, 255, 255), 2)

     cv2.imshow("Frame", frame)
     if cv2.waitKey(1) & 0xFF == 27:
          break
cap.release()
cv2.destroyAllWindows()

Al ejecutar los programas podrás obtener resultados con los siguientes:

Figura 2: Detección de rostros con dnn de OpenCV.

Figura 3: Detección de rostros con dnn de OpenCV.

Y bien, esto ha sido todo por el tutorial de hoy. ¡Espero que te haya gustado! 😊 Nos vemos en el siguiente… ¡Qué te vaya súper bien!.

Referencias

🔗 Blob: https://pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/

🔗 https://pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/
🔗 https://docs.opencv.org/3.4/d6/d0f/group__dnn.html#ga29f34df9376379a603acd8df581ac8d7
🔗 https://docs.opencv.org/3.4/db/d30/classcv_1_1dnn_1_1Net.html#a98ed94cb6ef7063d3697259566da310b
🔗 https://docs.opencv.org/3.4/d6/d0f/group__dnn.html#ga29f34df9376379a603acd8df581ac8d7
🔗 https://learnopencv.com/deep-learning-with-opencvs-dnn-module-a-definitive-guide/
🔗 https://github.com/opencv/opencv/tree/master/samples/dnn#face-detection