Detecta 543 puntos del cuerpo con ?? MEDIAPIPE HOLISTIC ?✋ | Python – MediaPipe – OpenCV

Por Administrador

¡Puedes detectar 543 puntos de referencia con MediaPipe Holistic!. ¡Sí!, esta es una solución que agrupa las que habíamos visto en tutoriales anteriores, es decir que nos permitirá detectar: la postura del cuerpo, malla facial y ambas manos. ¡Anímate a probarla!.

CONTENIDO

  • MediaPipe Holistic
    • ¿Cómo trabaja MediaPipe Holistic?
    • Modelos empleados en MediaPipe Holistic
      • Landmark model
      • Hand recrop model
    • Opciones de configuración
    • Datos de salida que obtenemos al usar MediaPipe Holistic
    • ¡Vamos con la programación!
      • MediaPipe Holistic en imágenes
      • MediaPipe Holistic en video
    • Referencias

MediaPipe Holistic

Figura 1: Ejemplo del uso de MediaPipe Holistic.

Ya hemos visto algunas soluciones de MediaPipe, en esta ocasión vamos a ver una que es la integración de las que habíamos visto antes, MediaPipe Holistic.  Esta integra los modelos separados de: postura, rostro y manos. Cada uno de ellos especializado en su trabajo.  

¿Cómo trabaja MediaPipe Holistic?

Figura 2: Procedimiento que realiza MediaPipe Holistic. (Fuente)

En primer lugar se estima la pose humana y sus puntos de referencia (que habíamos visto en mediapipe pose), estos últimos nos servirán para obtener la ubicación tanto de las dos manos, como del rostro. Una vez que se tiene la ubicación de cada uno de estos, se recorta de la imagen de entrada dichas regiones de interés, para obtener cada uno de los puntos de referencia de las manos y rostro. 

Recuerda que este es un pequeño resumen basado en la documentación de mediapipe holistic, ya que esta solución conlleva más procedimientos de recorte, redimensionamiento entre otros. 

Modelos empleados en MediaPipe Holistic

Figura 3: Modelos usados en MediaPipe Holistic

Ahora pasaremos a ver los modelos que se utilizan en MediaPipe Holistic. 

Landmark models

Mediapipe holistic utiliza los modelos de mediapipe poseface mesh y hands para generar un total 543 puntos de referencia, distribuidos de la siguiente manera: 

  • 33 puntos de referencia de postura 
  • 468 puntos de referencia del rostro 
  • 21 puntos de referencia por cada mano 

Hand recrop model

Este se utiliza en casos en los que la región de referencia de las manos es muy imprecisa, por lo que se ejecuta un modelo adicional para recortar nuevamente la región de interés de la mano. 

Opciones de configuración

STATIC_IMAGE_MODE (Por defecto  False) 

Si a este le asignamos False, entonces trata a las imágenes de entrada como un video, de tal forma que intentará detectar a la persona más prominente, así como los puntos de referencia en los primeros fotogramas. Para los siguientes fotogramas se realiza el seguimiento o tracking de los puntos ya ubicados. 

Si se especifica como True, la detección de la persona corre en todas las imágenes, por lo que es mejor usarlo en imágenes que no estén relacionadas. 

MODEL_COMPLEXITY (Por defecto 1) 

Puede tomar valores de 0, 1 o 2. Que corresponden a la complejidad del modelo pose landmark. La precisión y latencia generalmente aumenta con la complejidad del modelo. 

SMOOTH_LANDMARKS (Por defecto True)

Si se establece como True, se filtra los puntos de referencia de la postura a través de diferentes imágenes de entrada para reducir las fluctuaciones. Este es ignorado cuando static_image_mode es igual a True.

MIN_DETECTION_CONFIDENCE (Por defecto 0.5)

Valor mínimo de confianza del modelo de detección de la persona para que la detección se considere correcta. 

MIN_TRACKING_CONFIDENCE (Por defecto 0.5)

Valor mínimo de confianza del modelo de seguimiento de puntos de referencia para que los pose landmarks se consideren rastreados con éxito, de lo contrario la detección de persona se invocará automáticamente en la siguiente imagen de entrada. 

Este es ignorado si static_image_mode es igual a True. 

Datos de salida que obtenemos al usar MediaPipe Holistic

En las salidas tendremos las mismas que habíamos visto por separado en los anteriores videos, es decir: 

POSE_LANDMARKS 

En donde obtendremos sus cooredenadas x, y e z, y además visibility. Este ultimo es un valor comprendido entre 0 y 1 que indica la probabilidad de que el punto de referencia sea visible (presente y no ocluido) en la imagen. 

POSE_WORLD_LANDMARKS 

Figura 4: Visualización de la salida obtenida con POSE_WORLD_LANDMARKS.

Nos devolverá otra lista de los puntos de referencia de postura. En donde cada punto de referencia consta de coordenadas x, y e  z, es decir coordenadas 3D del mundo real en metros, con el origen en el centro entre las caderas. 

También nos devolverá visibility, que es similar al que habíamos visto en MediaPipe pose. 

FACE_LANDMARKS 

Donde obtendremos 468 puntos de referencia con sus coordenadas x, y e z. 

LEFT_HAND_LANDMARKS 

Tendremos una lista de 21 puntos de referencia con coordenadas x, y e z correspondientes a la mano izquierda.

RIGHT_HAND_LANDMARKS 

De igual forma obtendremos 21 puntos de referencia con coordenadas x, y e z correspondientes a la mano derecha.

¡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.

MediaPipe Holistic en imágenes

import cv2
import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils
mp_holistic = mp.solutions.holistic

with mp_holistic.Holistic(
     static_image_mode=True,
     model_complexity=2) as holistic:

     image = cv2.imread("imagen_0001.jpg")
     image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

     results = holistic.process(image_rgb)
     
     # rostro
     mp_drawing.draw_landmarks(
          image, results.face_landmarks, mp_holistic.FACE_CONNECTIONS,
          mp_drawing.DrawingSpec(color=(0, 255, 255), thickness=1, circle_radius=1),
          mp_drawing.DrawingSpec(color=(0, 128, 255), thickness=2))
     
     # Mano izquieda (azul)
     mp_drawing.draw_landmarks(
          image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS,
          mp_drawing.DrawingSpec(color=(255, 255, 0), thickness=2, circle_radius=1),
          mp_drawing.DrawingSpec(color=(255, 0, 0), thickness=2))
     
     # Mano derecha (verde)
     mp_drawing.draw_landmarks(
          image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS,
          mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=1),
          mp_drawing.DrawingSpec(color=(57, 143, 0), thickness=2))
     
     # Postura
     mp_drawing.draw_landmarks(
          image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS,
          mp_drawing.DrawingSpec(color=(128, 0, 255), thickness=2, circle_radius=1),
          mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2))

     cv2.imshow("Image", image)

     # Plot: puntos de referencia y conexiones en matplotlib 3D
     mp_drawing.plot_landmarks(
          results.pose_world_landmarks, mp_holistic.POSE_CONNECTIONS)
     cv2.waitKey(0)
cv2.destroyAllWindows()

MediaPipe Holistic en video

import cv2
import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils
mp_holistic = mp.solutions.holistic

#cap = cv2.VideoCapture("video_0001.mp4")
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

with mp_holistic.Holistic(
     static_image_mode=False,
     model_complexity=1) as holistic:

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

          frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
          results = holistic.process(frame_rgb)

           # rostro
          mp_drawing.draw_landmarks(
               frame, results.face_landmarks, mp_holistic.FACE_CONNECTIONS,
               mp_drawing.DrawingSpec(color=(0, 255, 255), thickness=1, circle_radius=1),
               mp_drawing.DrawingSpec(color=(0, 128, 255), thickness=2))
          
          # Mano izquieda (azul)
          mp_drawing.draw_landmarks(
               frame, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS,
               mp_drawing.DrawingSpec(color=(255, 255, 0), thickness=2, circle_radius=1),
               mp_drawing.DrawingSpec(color=(255, 0, 0), thickness=2))
          
          # Mano derecha (verde)
          mp_drawing.draw_landmarks(
               frame, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS,
               mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=1),
               mp_drawing.DrawingSpec(color=(57, 143, 0), thickness=2))
          
          # Postura
          mp_drawing.draw_landmarks(
               frame, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS,
               mp_drawing.DrawingSpec(color=(128, 0, 255), thickness=2, circle_radius=1),
               mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2))

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

cap.release()
cv2.destroyAllWindows()

Referencias