Estimación de Postura ? | Python – MediaPipe – OpenCV
Hasta aquí hemos hablado ya de MediaPipe hands (para la detección de manos y dedos), MediaPipe face detection (para la detección de rostros) y MediaPipe face mesh (malla facial). Cada una de estas soluciones vaya que nos ha sorprendido y además hemos aprendido como acceder a las detecciones obtenidas. En este tutorial vamos a tratar otra de las soluciones para Python, MediaPipe Pose.
CONTENIDO
- MediaPipe Pose
- Modelos empleados en MediaPipe Pose
- Person/pose Detection Model (BlazePose Detector)
- Pose Landmark Model (BlazePose GHUM 3D)
- Opciones de configuración
- Datos de salida que obtenemos al usar MediaPipe Pose
- ¡Vamos con la programación!
- Estimación de postura con MediaPipe en imágenes
- Estimación de postura con MediaPipe en videos
- Modelos empleados en MediaPipe Pose
- Referencias
MediaPipe Pose
Esta es una solución de machine learning de alta fidelidad, que permite obtener 33 puntos de referencia 3D de todo el cuerpo, teniendo como entrada, imágenes o fotogramas en rgb. Además esta solución alcanza resultados en tiempo real en la mayoría de teléfonos móviles modernos, computadores o laptops, e incluso en la web.
Modelos empleados en MediaPipe Pose
Para la obtención de los 33 puntos de referencia, esta solución emplea un proceso similar al visto en MediaPpe Hands y en MediaPipe FaceMesh, trabajando con dos modelos. El primer modelo se encargará de ubicar a la persona dentro de la imagen, mientras que el segundo ubicará los 33 puntos claves o puntos de referencia.
Person/pose Detection Model (BlazePose Detector)
Se emplea en un principio un modelo para la detección de la persona o postura, blazePose. Que por cierto está basado en el modelo BlazeFace que se emplea en mediaPipe face detection. Entonces, este modelo ubica a la persona dentro de la imagen, es decir la región de interés y recorta dicha región.
Pose Landmark Model (BlazePose GHUM 3D)
Una vez que se tiene la imagen recortada donde está presente la persona, se procede a aplicar el pose landmark model, que nos permitirá obtener la ubicación de 33 puntos distribuidos por todo el cuerpo. Cada uno de estos tendrá un nombre asociado que más adelante veremos como acceder.
Si tenemos como entrada a un video, al igual que en anteriores tutoriales, el detector de la persona se aplicará en los primeros fotogramas y luego se realizará la obtención de los puntos clave, para que en fotogramas posteriores dichos puntos sean rastreados, de tal forma que solo se invoque al detector de personas cuando se hayan perdido dichos puntos.
En sí, este es un resumen del proceso de detección que podemos encontrar en la documentación de MediaPipe Pose, por lo que si quieres una explicación más extendida, te recomiendo que visites su web y su repositorio.
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 y los puntos de referencia en los primeros fotogramas. Mientras que para localizar la nueva ubicación de los puntos, se procederá a realizar el seguimiento o tracking de los puntos de referencia.
Si se especifica como True, el detector se aplica en cada imagen, 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. Y lo que nos dice la documentación es que 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 personas 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 personas 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 Pose
POSE_LANDMARKS
Una lista de puntos de referencia de la postura. Cada uno de ellos contará con sus coordenadas x, y y z. Además tendremos visibility, este 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.
¡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.
Estimación de postura con MediaPipe en imágenes
import cv2 import mediapipe as mp mp_drawing = mp.solutions.drawing_utils mp_pose = mp.solutions.pose with mp_pose.Pose( static_image_mode=True) as pose: image = cv2.imread("image_0001.jpg") height, width, _ = image.shape image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = pose.process(image_rgb) print("Pose landmarks:", results.pose_landmarks) if results.pose_landmarks is not None: print(int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER].x * width)) x1 = int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER].x * width) y1 = int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER].y * height) x2 = int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ELBOW].x * width) y2 = int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ELBOW].y * height) x3 = int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST].x * width) y3 = int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST].y * height) x4 = int(results.pose_landmarks.landmark[11].x * width) y4 = int(results.pose_landmarks.landmark[11].y * height) x5 = int(results.pose_landmarks.landmark[13].x * width) y5 = int(results.pose_landmarks.landmark[13].y * height) x6 = int(results.pose_landmarks.landmark[15].x * width) y6 = int(results.pose_landmarks.landmark[15].y * height) cv2.line(image, (x1, y1), (x2, y2), (255, 255, 255), 3) cv2.line(image, (x2, y2), (x3, y3), (255, 255, 255), 3) cv2.circle(image, (x1, y1), 6, (128, 0, 255), -1) cv2.circle(image, (x2, y2), 6, (128, 0, 255), -1) cv2.circle(image, (x3, y3), 6, (128, 0, 255), -1) cv2.line(image, (x4, y4), (x5, y5), (255, 255, 255), 3) cv2.line(image, (x5, y5), (x6, y6), (255, 255, 255), 3) cv2.circle(image, (x4, y4), 6, (255, 191, 0), -1) cv2.circle(image, (x5, y5), 6, (255, 191, 0), -1) cv2.circle(image, (x6, y6), 6, (255, 191, 0), -1) ''' mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, mp_drawing.DrawingSpec(color=(128, 0, 250), thickness=2, circle_radius=3), mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2)) ''' cv2.imshow("Image", image) cv2.waitKey(0) cv2.destroyAllWindows()
Estimación de postura con MediaPipe en video
import cv2 import mediapipe as mp mp_drawing = mp.solutions.drawing_utils mp_pose = mp.solutions.pose #cap = cv2.VideoCapture("video_0002.mp4") cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) with mp_pose.Pose( static_image_mode=False) as pose: while True: ret, frame = cap.read() if ret == False: break frame = cv2.flip(frame, 1) height, width, _ = frame.shape frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = pose.process(frame_rgb) if results.pose_landmarks is not None: mp_drawing.draw_landmarks( frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, mp_drawing.DrawingSpec(color=(128, 0, 250), thickness=2, circle_radius=3), mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2)) cv2.imshow("Frame", frame) if cv2.waitKey(1) & 0xFF == 27: break cap.release() cv2.destroyAllWindows()
Hola, tengo un proyecto de realizar la detección de movimientos en tiempo real para saber si una persona realiza los mismos movimientos (o lo mas cercano posible) que se realizan en un video, algo como calificar los pasos de baile de acuerdo a una coreografía que estarían viendo en un video, si pudiera ayudarme a orientarme como podría saber si hace los mismos pasos, ya realice tus tutoriales de mediapie pose, pero me atore en la parte de calificar los pasos.
Hola Irving, puede que este tutorial te ayude: https://youtu.be/qVaDIDtoIZk
Hola, estoy probando el código de Estimación de postura con MediaPipe en video y me aparece el siguiente error:
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
sabes porque pasa esto ?
Hola Laura, no te preocupes es solo un mensaje de información. 🙂
hola, al ejecutar el codigo me sale este error:
Descriptors cannot not be created directly.
If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0.
If you cannot immediately regenerate your protos, some other possible workarounds are:
1. Downgrade the protobuf package to 3.20.x or lower.
2. Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and will be much slower).
More information: https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates
Hola qué tal?
Disculpa, sabrás cuales son los requisitos mínimos de resolución de vídeo para el uso de esta solución?
Hola, tenia una consulta, si quisiera que en un video se detectara varias personas a la vez y dibujara su pose que puedo hacer?
Se me ocurrida usar un modelo de haarcascade cada cierto punto y de ella aplicar el modelo de pose pero no estoy muy seguro