dlib localiza 68 puntos en cada cara: el contorno de la mandíbula, las cejas, la nariz, los ojos y la boca. Con ellos se puede medir si alguien tiene los ojos cerrados, hacia dónde mira o si está sonriendo. Antes de empezar, dos avisos: cuesta instalarlo, y el modelo de 68 puntos no se puede usar en un producto comercial.
También te puede interesar
Instalarlo
sudo apt install cmake g++ # en Debian o Ubuntu pip install dlib opencv-python-headless
pip install dlib no descarga un paquete ya hecho: compila dlib desde el código fuente, y para eso necesita cmake y un compilador de C++. En nuestra prueba tardó varios minutos. En Windows hace falta Visual Studio con las herramientas de C++.
sudo pip3 install. No uses sudo con pip: instala en el Python del sistema y puede romper programas que dependen de él. Usa un entorno virtual. Tampoco hace falta ya imutils: era para una sola conversión que se hace en una línea.El modelo, y su licencia
Los puntos los calcula un modelo ya entrenado, shape_predictor_68_face_landmarks.dat, que se baja del repositorio de modelos de dlib. Pesa unos 100 MB.
Los 68 puntos
import cv2, dlib
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
imagen = cv2.imread("tripulacion.jpg")
gris = cv2.cvtColor(imagen, cv2.COLOR_BGR2GRAY)
caras = detector(gris, 1)
print("caras:", len(caras))
for cara in caras:
forma = predictor(gris, cara)
puntos = [(forma.part(i).x, forma.part(i).y) for i in range(forma.num_parts)]
print(f" cara en ({cara.left()}, {cara.top()}): {len(puntos)} puntos")
for (x, y) in puntos:
cv2.circle(imagen, (x, y), 2, (60, 200, 60), -1)
cv2.imwrite("resultado_dlib.jpg", imagen)salidacaras: 3 cara en (259, 343): 68 puntos cara en (808, 355): 68 puntos cara en (534, 186): 68 puntos

Dos pasos: primero el detector de caras propio de dlib —que acertó las tres, sin el falso positivo de las cascadas Haar—, y luego el predictor, que coloca los puntos dentro de cada cara. El 1 de detector(gris, 1) amplía la imagen una vez antes de buscar, para encontrar caras más pequeñas. La lista de puntos se construye directamente con part(i), que es lo único que hacía imutils.
Qué punto es cada cosa
| Zona | Puntos |
|---|---|
| Mandíbula | 0 a 16 |
| Cejas | 17 a 26 |
| Nariz | 27 a 35 |
| Ojos | 36 a 47 (seis por ojo) |
| Boca | 48 a 67 |
Un ejemplo de uso: ¿tiene el ojo abierto?
ojo = puntos[36:42]
ancho_ojo = abs(ojo[3][0] - ojo[0][0])
alto_ojo = (abs(ojo[1][1] - ojo[5][1]) + abs(ojo[2][1] - ojo[4][1])) / 2
print(f"apertura del ojo: {alto_ojo / ancho_ojo:.2f}")salidaapertura del ojo: 0.35
Con los seis puntos de un ojo se compara su altura con su anchura. Un ojo abierto da en torno a 0,3; si el valor cae cerca de cero durante varios fotogramas seguidos, la persona tiene los ojos cerrados. Es la base de los sistemas que avisan a un conductor cuando se está durmiendo.
Más información en inglés: Face mapping with dlib and Python.
Todo el código se ejecutó con Python 3.14 en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.