Landmarks para Dlib shape_predictor_68 con triangulación Delaunay

Detección de caras y Triangulación de Delaunay con Dlib y OpenCV

--

Introducción

En el 90% de los casos en que busco algo relacionado a detección / reconocimiento de caras, obtengo como resultado fotos de personas con una especie de grilla de puntos conectados por líneas en sus rostros. Como si de alguna forma esos triángulos o polígonos delimitados por puntos especiales del rostro, fueran lo que “ven” los algoritmos de reconocimiento facial.

Lo interesante es que estos puntos, que en la literatura se conocen como “face landmarks”, son esenciales para muchas aplicaciones y modelos de visión por computadora. Por ejemplo los modelos que pueden predecir a partir de una imagen de un rostro, si la persona está “feliz”, “enojada”, “triste”… También son esenciales en el funcionamiento de los famosos filtros para selfies, de aplicaciones como Snapchat, Instagram o Tik Tok.

GETTY IMAGES

No estoy tan seguro si sucede lo mismo con estas famosas grillas. Lo cierto, es que independientemente de su utilidad, que seguramente la tengan, queda muy bien en cualquier presentación de un producto de reconocimiento facial.

Cuando aparece una diapositiva como estas — ¡boom! — el cliente inmediatamente piensa en CSI Miami, Horatio Caine y la búsqueda de un sospechoso criminal y vualá, tenemos su atención.

Por eso en este tutorial voy a mostrar cómo detectar el rostro de una persona a partir de una imagen, obtener sus face landmarks y por último utilizando una técnica conocida como Triangulación de Delaunay, dibujar una grilla de triángulos sobre el rostro.

¿Qué es la Triangulación de Delaunay?

Boris Nikolaevich Delaunay, fue un destacado matemático ruso en la época soviética, famoso entre otros logros por el método de triangulación que lleva su nombre. Su mentor fue un destacado matemático ucraniano llamado Gueorgui Voronói, autor de los diagramas de Voronoi, quien a su vez tuvo como mentor a nada más, ni nada menos que a Andréi Márkov (creador de las cadenas de Markov y procesos Markovianos).

Ahora que entramos en contexto, veamos de qué va la famosa triangulación de Delaunay.

Dado un conjunto de puntos en un plano, una triangulación refiere al proceso de subdividir el plano en triángulos, de forma que los vértices de estos se correspondan con los puntos del conjunto.

Naturalmente para un conjunto de puntos en un plano, existen tantas triangulaciones como combinaciones de triángulos, pero la triangulación de Delaunay es aquella en la que todos los triángulos cumplen la siguiente condición:

Dados los vértices de un triángulo y la circunferencia que los contiene en su perímetro (circunferencia circunscrita), no puede existir otro vértice de la triangulación en su interior, si se admiten en el perímetro.

Ejemplos de la condición de Delaunay

La condición de Delaunay, origina una triangulación con varias propiedades interesantes. Una de ellas es que el ángulo mínimo dentro de todos los triángulos está maximizado, es decir, se evita obtener resultados con ángulos demasiado agudos, lo cual favorece a los triángulos “anchos”.

Conectando los centros de las circunferencias circunscritas se produce el diagrama de Voronoi (en rojo).

Por otro lado, la triangulación de Delaunay y el diagrama de Voronoi de una serie de puntos son grafos duales, por lo que la construcción de uno es trivial a partir del otro. En este sentido, los circuncentros de los triángulos de Delaunay coinciden con los vértices de las regiones del diagrama de Voronoi. Por otro lado, dos vértices del diagrama de Voronoi estarán conectados si sus triángulos de Delaunay correspondientes son vecinos entre sí.

¿Qué es un diagrama de Voronoi?

Los diagramas de Voronoi o también conocidos como Teselación de Voronoi, es una construcción geométrica que permite calcular una partición del plano euclidiano, a partir de un conjunto de puntos. Esta partición da lugar a un conjunto de polígonos con la propiedad especial de que sus aristas equidistan de los puntos vecinos del conjunto.

20 puntos en el plano y su partición del plano en regiones de Voronoi.

Los diagramas de Voronoi también cumplen una serie interesante de propiedades en las que no vamos a profundizar en este artículo (más información).

Implementación

Basta de fundamentos teóricos, vayamos directo al código y veamos paso a paso cómo detectar rostros, obtener los landmarks y a partir de estos calcular la Triangulación de Delaunay y diagrama de Voronoi.

Para ello vamos a utilizar fundamentalmente dos bibliotecas de Python, ampliamente conocidas para procesamiento de imágenes: Dlib y OpenCV.

Pasos en el pipeline para hallar triangulación de Delaunay y diagrama de Voronoi

1. Detección de la cara

Lo primero que vamos a hacer es detectar el o los rostros de personas en la imagen. Para ello vamos a utilizar el método get_frontal_face_detector de la biblioteca Dlib. Esta biblioteca incluye varios modelos pre-entrenados para una gran variedad de tareas y problemas dentro de Computer Vision. En particular, este método devuelve un detector basado en HOG (Histogram of oriented gradients) + SVM, aunque también cuenta con detectores basados en Redes Neuronales Convolucionales (CNN).

Entonces, leemos la imagen (para este ejemplo yo utilicé una imagen de Lucho) y la convertimos a escala de grises, utilizando OpenCV. Es importante este último paso ya que el detector de Dlib espera recibir una imagen en escala de grises. Por último invocamos al detector para obtener las predicciones.

Notar que por comodidad ya defino el modelo que vamos a utilizar para reconocer los landmarks (predictor).

2. Reconocimiento de Face Landmarks

Para obtener los landmarks del rostro vamos a utilizar el método shape_predictor también de la biblioteca Dlib. Este modelo es una implementación de Dlib del artículo One Millisecond Face Alignment with an Ensemble of Regression Trees by Vahid Kazemi and Josephine Sullivan. Además existe más de una implementación de este estimador, yo utilicé shape_predictor_68_face_landmarks que reconoce 68 puntos (ver siguiente figura).

68 puntos en shape_predictor — Foto iBUG 300-W

Entonces tomo la primera cara reconocida por el detector y se la paso al shape_predictor. Este último toma como argumentos la imagen completa en escala de grises y la bounding box en donde se encuentra la cara, y devuelve las coordenadas estimadas para los 68 puntos de la cara.

Por comodidad de aquí en más hice todo el procesamiento para la primera cara detectada, pero tú puedes fácilmente extender el código para procesar todas las caras detectadas.

En las últimas dos líneas lo que hacemos es convertir el resultado a una lista de tuplas de Python, para trabajar más cómodamente.

3. Hallar Triangulación Delaunay

Para hallar la triangulación de Delaunay vamos a utilizar la clase Subdiv2D de OpenCV y los face landmarks calculados en el paso anterior. Esta clase permite realizar una variedad de subdivisiones en un plano (2D), entre las cuales se encuentran Delaunay y Voronoi.

Para crear la subdivisión le pasamos un rectángulo del mismo tamaño que la imagen y agregamos uno a uno los landmarks. Luego con los métodos getTriangleList y getVoronoiFacetList también de Subdiv2D, obtenemos las divisiones de Delaunay y Voronoi respectivamente. Por comodidad, encapsulo el llamado a estos métodos junto a algunos pasos básicos en los métodos draw_delaunay y draw_voronoi.

Métodos auxiliares para calcular y dibujar triangulación, puntos, etc.

— ¡Y eso es todo! —

Conclusiones

Recapitulando, leímos una imagen a partir de un archivo, detectamos las caras utilizando el detector que trae por defecto Dlib y con el shape_predictor también de Dlib, obtuvimos sus landmarks. Por último, utilizando la clase Subdiv2D de OpenCV calculamos la triangulación de Delaunay y los diagramas de Voronoi.

¡Todo el código disponible en mi Github!.

Si tienes algún comentario, duda o sugerencia por favor envíamela a través de los comentarios, los tendré muy en cuenta. Y por supuesto, si te gusto este post por favor compártelo!

Sígueme en Twitter @Efviodo o en Linkedin para enterarte de nuevos posts y otros proyectos sobre IA en los que estoy involucrado.

--

--

Emiliano Viotti
IDATHA // Enterprise Experience & Academic´s

Machine Learning Director at IDATHA.com — AI Builder — CV and NLP practitioner — Hungry reader and stories writer — Former professor at Fing UdelaR.