EMPATIA AUTOMATIZADA (3) – Detección de Rostros y Facial Landmark

por | octubre 15, 2016

Para la detección de rostros he probados dos técnicas, que explicaré a continuación:

-OPENCV: a partir de la versión 3 de OpenCV ya vienen ejemplos de detección detección de rostros mediante clasificadores ya entrenados con mucho éxito.

-DLIB: son unas librerías de C++ que contienen algoritmos de aprendizaje automático y herramientas para facilitar la creación de aplicaciones en  C ++ para resolver problemas mediante minería de datos, visión artificial y otras técnicas.

Después de hacer pruebas con ambas técnicas he llegado a la conclusión de que DLIB tiene mejor resuelta la detección de rostros, como veréis en el código en un par de instrucciones se puede realizar, y con un grado de precisión mucho mejor que con OPENCV.

Como curiosidad os indico un link a un video que usa las dos técnicas a la vez (aunque no comparte el código y no podemos saber exactamente cómo de bien lo está haciendo).

OpenCV vs Dlib

Finalmente, he conseguido tener un código en C++ que detecta en tiempo real los rostros presentes en la imagen y me da las coordenadas de los 68 puntos representativos (facial landmark).

Introduciendo a los peques en la visión artificial

Introduciendo a los peques en la visión artificial

En el siguiente artículo analizaré todos los datos mediante Data Mining para ver con qué datos me quedo, aunque supongo que los 68 puntos son el resultado de análisis estadísticos realizados por expertos, y que son el mínimo número de puntos con representatividad.

Os dejo el código para que probéis.

(bajaros primero DLIB, yo uso la v19.0, guardadlo en C:, añadid la variable de entorno, los includes al proyecto visual, etc…)

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/image_transforms.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_io.h>
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d.hpp>
#include <dlib/opencv.h>
#include <dlib/opencv/cv_image.h>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>using namespace dlib;
using namespace std;

int main()
{
// Usamos un detector de rostros frontal.
frontal_face_detector detector = get_frontal_face_detector();

// Cargamos el predictor y deserializamos el archivo .dat ya entrenado por otra gente (y almacenado en nuestra carpeta)
shape_predictor sp;
deserialize(«../predictor/shape_predictor_68_face_landmarks.dat») >> sp;

// Creamos la ventana donde se mostrará el video
image_window ventana;

// Comenzamos la detección mediante la webcam
cv::VideoCapture cap(0);

// Indicamos el tamaño del frame
cap.set(cv::CAP_PROP_FRAME_WIDTH, 800);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 600);

if (!cap.isOpened())
{
cerr << «Error al conectar con la camara» << endl;
return 1;
}

// Bucle que no acaba hasta que el usuario cierra la ventana.
while (!ventana.is_closed())
{
// Tomamos un frame
cv::Mat temp;
cap >> temp;
cv_image<bgr_pixel> cimg(temp);

// Aplicamos el detector a la imagen en formato cv_image y obtenemos como resultado el vector faces
std::vector<rectangle> vector_rostros = detector(cimg);
cout << «Numero de caras detectadas: » << vector_rostros.size() << endl;

// Encuentra los puntos de cada rostro y nos muestra las coordenadas (sólo he puesto unos cuantos como muestra)
std::vector<full_object_detection> vector_puntos;
for (unsigned long i = 0; i < vector_rostros.size(); ++i)
{
full_object_detection shape = sp(cimg, vector_rostros[i]);
cout << «Numero de puntos: » << shape.num_parts() << endl;
cout << «Coordenadas punto 1: » << shape.part(0) << endl;
cout << «Coordenadas punto 2: » << shape.part(1) << endl;
cout << «Coordenadas punto 3: » << shape.part(2) << endl;
cout << «Coordenadas punto 4: » << shape.part(3) << endl;
cout << «Coordenadas punto 5: » << shape.part(4) << endl;
cout << «Coordenadas punto 6: » << shape.part(5) << endl;
cout << «Coordenadas punto 7: » << shape.part(6) << endl;
cout << «Coordenadas punto 8: » << shape.part(7) << endl;
cout << «Coordenadas punto 9: » << shape.part(8) << endl;
cout << «Coordenadas punto 10: » << shape.part(9) << endl;
cout << «Coordenadas punto 11: » << shape.part(10) << endl;
cout << «Coordenadas punto 12: » << shape.part(11) << endl;
cout << «Coordenadas punto 68: » << shape.part(67) << endl;
vector_puntos.push_back(shape);
}

// Muestra el frame
ventana.set_title(«Facial Landmark»);
ventana.clear_overlay();
ventana.set_image(cimg);

// Añade al frame los puntos con circulitos
ventana.add_overlay(vector_puntos);

// Esta instrucción mostraría todos los puntos unidos.
//win.add_overlay(render_face_detections(shapes));

}
}

Facebooktwitterredditpinterestlinkedinmail

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *