Malla Facial (MediaPipe Face Mesh) ? | Python – MediaPipe – OpenCV
Ya hemos explorado dos de las soluciones que nos ofrece MediaPipe, la primera fue MediaPipe Hands para la detección de manos y dedos. Luego MediaPipe FaceDetection, para la detección de rostros o caras que a su vez se aplica en la solución que veremos hoy. En este tutorial, vamos a hablar de MediaPipe Face Mesh.
CONTENIDO:
- MediaPipe Face Mesh
- Modelos empleados en MediaPipe Face Mesh
- Face detection model
- Face landmark model
- Opciones de configuración
- Datos de salida que obtenemos al usar MediaPipe Face Mesh
- ¡Vamos con la programación!
- Malla Facial con MediaPipe en imágenes
- Malla Facial con MediaPipe en videos
- Referencias
- Modelos empleados en MediaPipe Face Mesh
MediaPipe Face Mesh
Según su documentación, esta es una solución de geometría de caras, que nos permite obtener 468 puntos claves 3D, en tiempo real que incluso puede ser aplicada en dispositivos móviles.
Esta solución emplea machine learning, y usa tan solo una cámara para obtener los puntos 3D de la superficie geométrica, por lo que no es necesario un sensor de profundidad.
Modelos empleados en MediaPipe Face Mesh
Esta solución emplea dos modelos de redes neuronales profundas que trabajan juntas y en tiempo real. Así que vamos a hablar un poco de cada uno de ellos:
FACE DETECTION MODEL
Este modelo es el mismo usado por MediaPipe Face Detection, del anterior videotutorial. Este detector de rostros opera sobre toda la imagen para obtener el o los lugares en donde están presentes los rostros.
Una vez que se tiene ubicada esta región de la imagen, se procede al empleo del siguiente modelo.
FACE LANDMARK MODEL
Este modelo opera sobre las ubicaciones de los rostros detectados y genera las posiciones de los puntos 3D.
Cabe destacar que face mesh, sigue un proceso similar al de mediapipe hands, es decir que los landmarks (puntos claves o puntos de referencia) se van obteniendo basándose en el fotograma anterior, es decir mediante el tracking o seguimiento de ellos. Y se invoca nuevamente al detector de rostros, es decir al anterior modelo, únicamente cuando no se haya podido identificar la presencia de la cara.
Hemos visto un pequeño resumen del proceso que emplea mediapipe face mesh para la detección de los rostros y de los 468 puntos de referencia, para una explicación más extendida puedes dirigirte a la documentación de mediapipe face mesh.
OPCIONES DE CONFIGURACION
STATIC_IMAGE_MODE (Por defecto false)
Puede tomar valores de True o False. Si especificamos este como False, entonces la solución trata a las imágenes de entrada como un videostream, por lo que intentará detectar el o los rostros en las primeras imágenes de entrada, y cuando se haya realizado una detección exitosa, se localizarán los puntos de referencia. En las imágenes siguientes una vez que se hayan obtenido los puntos de referencia o puntos clave, estos serán rastreados para conseguir la nueva ubicación de los rostros, y solo se invocará nuevamente al detector de rostros una vez que ya no se haya podido identificar la presencia de una cara. Debido a que no se tiene que aplicar una y otra vez el detector de rostros, y simplemente se da seguimiento a los puntos de referencia, se puede reducir la latencia, por lo que es ideal para usarla en videos.
Por otro lado si especificamos STATIC_IMAGE_MODE como True, se aplica el detector de rostros en cada una de las imágenes de entrada, por lo que es mejor usar esta cuando tenemos imágenes que no se relacionan entre sí.
NUM_MAX_FACES (Por defecto 1)
Número máximo de rostro a detectar
MIN_DETECTION_CONFIDENCE (Por defecto 0.5)
Valor mínimo de confianza del modelo de detección facial, para que la detección sea considerada como exitosa.
MIN_TRACKING_CONFIDENCE (Por defecto 0.5)
Valor mínimo de confianza del modelo de seguimiento de puntos de referencia (landmark-trancking), para que estos se consideren como seguidos correctamente. De lo contrario se invoca a la detección de rostros en la siguiente imagen.
Este es ignorado si STATIC_IMAGE_MODE lo especificamos como True, ya que en ese caso el detector de rostros será aplicado en todas las imágenes.
Datos de salida que obtenemos al usar MediaPipe Face Mesh
MULTI_FACE_LANDMARKS
Colección de rostros detectados o seguidos, donde cada rostro es representado como una lista de 468 puntos clave y cada punto está compuesto de x, y e z.
¡Vamos con la programación!
Para una explicación más detallada de los programas que veremos a continuación, por favor dirígete al videotutorial de mi canal.
Malla facial con MediaPipe en imágenes
import cv2 import mediapipe as mp mp_face_mesh = mp.solutions.face_mesh mp_drawing = mp.solutions.drawing_utils index_list = [70, 63, 105, 66, 107, 336, 296, 334, 293, 300, 122, 196, 3, 51, 281, 248, 419, 351, 37, 0, 267] with mp_face_mesh.FaceMesh( static_image_mode=True, max_num_faces=3, min_detection_confidence=0.5) as face_mesh: image = cv2.imread("imagen_0001.jpg") height, width, _ = image.shape image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = face_mesh.process(image_rgb) print("Face landmarks: ", results.multi_face_landmarks) if results.multi_face_landmarks is not None: for face_landmarks in results.multi_face_landmarks: for index in index_list: x = int(face_landmarks.landmark[index].x * width) y = int(face_landmarks.landmark[index].y * height) cv2.circle(image, (x, y), 2, (255, 0, 255), 2) cv2.imshow("Image", image) cv2.waitKey(0) ''' if results.multi_face_landmarks is not None: for face_landmarks in results.multi_face_landmarks: mp_drawing.draw_landmarks(image, face_landmarks, mp_face_mesh.FACE_CONNECTIONS, mp_drawing.DrawingSpec(color=(0, 255, 255), thickness=-1, circle_radius=1), mp_drawing.DrawingSpec(color=(255, 0, 255), thickness=1)) ''' cv2.imshow("Image", image) cv2.waitKey(0) cv2.destroyAllWindows()
Malla facial con MediaPipe en videos
import cv2 import mediapipe as mp mp_face_mesh = mp.solutions.face_mesh mp_drawing = mp.solutions.drawing_utils cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) with mp_face_mesh.FaceMesh( static_image_mode=False, max_num_faces=1, min_detection_confidence=0.5) as face_mesh: while True: ret, frame = cap.read() if ret == False: break frame = cv2.flip(frame,1) frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = face_mesh.process(frame_rgb) if results.multi_face_landmarks is not None: for face_landmarks in results.multi_face_landmarks: mp_drawing.draw_landmarks(frame, face_landmarks, mp_face_mesh.FACE_CONNECTIONS, mp_drawing.DrawingSpec(color=(0, 255, 255), thickness=1, circle_radius=1), mp_drawing.DrawingSpec(color=(255, 0, 255), thickness=1)) cv2.imshow("Frame", frame) k = cv2.waitKey(1) & 0xFF if k == 27: break cap.release() cv2.destroyAllWindows()
Referencias
- Mediapipe Face Mesh: https://google.github.io/mediapipe/solutions/face_mesh
- canonical_face_model_uv_visualization: https://github.com/google/mediapipe/blob/master/mediapipe/modules/face_geometry/data/canonical_face_model_uv_visualization.png
Hola Gaby que gusto poder escribirte tal vez no me leas, pero tal vez si jaj, bueno estoy seguro que no me vas a creer pero soy un niño de 12 años un poco introducido en este tema de la visión por computadora con Python y openCV me gusta seguir tus tutoriales y reforzar mi conocimiento me ha encantado este tutorial pero no me funciona, me sale que el modulo mp.solutions.face_mesh no atribute con el método FACE_CONNECTIONS he escrito y escrito y escrito una y otra vez el tutorial pero no me funciona me podrías ayudar bueno claro si te quito tiempo mejor no.
Por cierto tengo un canal de YouTube soy de Perú jjaj tengo 4 suscriptores compañeros de colegio, me gustaría que vieras algunos videos que pronto estaré subiendo solo tengo 1 hoy subo el de los puntos de segmentación en la manos se podría decir que son shorts porque no duran mucho pero bueno este es el link https://www.youtube.com/channel/UCCvkrvl0b4PyQEVnIIetybw .
y este es el link de mi primer videito : https://www.youtube.com/watch?v=InE0elvhmZ0
Bueno Quería decirte como palabras finales que estoy muy agradecido con su persona, con usted señorita por el tiempo y la dedicación que usted pone en sus tutoriales para apoyar a la comunidad, una vez mas muchas gracias, algún día me gustaría poder conocerla, usted es una muy buena persona y esto se puede ver reflejado en el cariño hacia la comunidad que tiene por tratar de apoyar siempre a sus suscriptores (yo también lo soy) de solucionar sus problemas. MUCHAS GRACIAS.
Y hasta la próxima.
Firma: Justin Douglas Peredo Zumaeta
Bellavista Callao.
Hola Justin, mucho gusto. Qué bonito que te esté gustando el campo desde esa edad, espero que te vaya súper bien y aprendas mucho. Tus papitos deben estar muy contentos. 🙂 Con respecto a la duda que tienes, debe ser debido a las nuevas actualizaciones que presenta MediaPipe. Pero no te preocupes, en la descripción de cada videotutorial de Mediapipe puedes encontrar las versiones con las que se ha probado exitosamente, puedes probarlas y divertirte un poco.
Espero que te vaya super bien en tu canal y más que todo que te diviertas mucho. Un abrazo grande y sigue adelante. Muchos muchos éxitos.
Gaby Gaby soy yo otra vez ya descubrí que me paso no si si este método se actualizo pero ahora el método que se usa es FACEMESH_TESSELATION GRACIAS Y DISCULPA SI TE HICE PERDER TIEMPO
Con FACEMESH_TESSELATION te une los puntos en triangulos y con FACEMESH_CONTOURS solo pone el punto
excelente tutorial!
Muchas gracias Williams Bobadilla. 🙂
Hola genial tu trabajo muchas gracias por compartir, solo paso a contar que mp_face_mesh.FACE_CONNECTIONS cambio por mp_face_mesh.FACEMESH_TESSELATION, aquí hay mas detalles: https://stackoverflow.com/questions/69095372/attributeerror-module-mediapipe-python-solutions-holistic-has-no-attribute-f
mil gracias
Hola Gaby muy buen video, solo tengo una duda y es si aun es posible acceder a las coordenadas x,y del rostro para poder dibujar el cuadrado que encierre el rostro, es que me gustaría poder poner la malla al rostro y además el cuadrado.
Saludos y perdón por las molestias.
Hola genia!!! Mira, estuve haciendo este tutorial que propones, pero como siempre… «Houston, we have a problem»: me aparece este error:
Traceback (most recent call last):
File «C:\Users\Jose Gomez\Desktop\pyprj\MallaFacial\main.py», line 20, in
mp_face_mesh.FACE_CONNECTIONS,
AttributeError: module ‘mediapipe.python.solutions.face_mesh’ has no attribute ‘FACE_CONNECTIONS’
Hola, en unos comentarios mas arriba otra persona ya puso la corrección! suertee!!!