Seguimiento de pose humana con MediaPipe en 2D y 3D: repetición de escaparate |  de Andreas Naoum |  marzo de 2024

Cómo visualizar fácilmente el seguimiento de la pose humana de MediaPipe con Rerun

Seguimiento de postura humana | Imagen por autor

Exploramos un caso de uso que aprovecha el poder de Tubo de medios para rastrear poses humanas tanto en 2D como en 3D. Lo que hace que esta exploración sea aún más fascinante es el aspecto de visualización impulsado por la herramienta de visualización de código abierto. Repeticiónque proporciona una visión holística de las poses humanas en acción.

En esta publicación de blog, se le guiará sobre el uso de MediaPipe para realizar un seguimiento de las poses humanas en 2D y 3D, y explorar las capacidades de visualización de Rerun.

El seguimiento de la pose humana es una tarea de visión por computadora que se centra en identificar ubicaciones clave del cuerpo, analizar la postura y categorizar los movimientos. En el corazón de esta tecnología se encuentra un modelo de aprendizaje automático previamente entrenado para evaluar la información visual y reconocer puntos de referencia en el cuerpo tanto en coordenadas de imagen como en coordenadas mundiales en 3D. Los casos de uso y aplicaciones de esta tecnología incluyen, entre otros, interacción persona-computadora, análisis deportivo, juegos, realidad virtual, realidad aumentada, salud, etc.

Sería bueno tener un modelo perfecto, pero lamentablemente los modelos actuales siguen siendo imperfectos. Aunque los conjuntos de datos pueden tener una variedad de tipos de cuerpo, el cuerpo humano difiere entre los individuos. La singularidad del cuerpo de cada individuo plantea un desafío, particularmente para aquellos con dimensiones de brazos y piernas no estándar, lo que puede resultar en una menor precisión al usar esta tecnología. Al considerar la integración de esta tecnología en los sistemas, es crucial reconocer la posibilidad de imprecisiones. Con suerte, los esfuerzos en curso dentro de la comunidad científica allanarán el camino para el desarrollo de modelos más sólidos.

Más allá de la falta de precisión, surgen consideraciones éticas y legales al utilizar esta tecnología. Por ejemplo, capturar poses del cuerpo humano en espacios públicos podría potencialmente invadir los derechos de privacidad si las personas no han dado su consentimiento. Es fundamental tener en cuenta cualquier preocupación ética y legal antes de implementar esta tecnología en escenarios del mundo real.

Comience instalando las bibliotecas necesarias:

# Install the required Python packages 
pip install mediapipe
pip install numpy
pip install opencv-python<4.6
pip install requests>=2.31,<3
pip install rerun-sdk

# or just use the requirements file
pip install -r examples/python/human_pose_tracking/requirements.txt

Imagen vía Guía de detección de puntos de referencia de Pose por Google [1]

MediaPipe Python es una herramienta útil para desarrolladores que buscan integrar soluciones de aprendizaje automático en el dispositivo para visión por computadora y aprendizaje automático.

En el siguiente código, Detección de puntos de referencia de pose de MediaPipe se utilizó para detectar puntos de referencia de cuerpos humanos en una imagen. Este modelo puede detectar puntos de referencia de poses corporales como coordenadas de imagen y coordenadas mundiales en 3D. Una vez que haya ejecutado correctamente el modelo ML, puede utilizar las coordenadas de la imagen y las coordenadas del mundo 3D para visualizar el resultado.

import mediapipe as mp
import numpy as np
from typing import Any
import numpy.typing as npt
import cv2

"""
Read 2D landmark positions from Mediapipe Pose results.

Args:
results (Any): Mediapipe Pose results.
image_width (int): Width of the input image.
image_height (int): Height of the input image.

Returns:
np.array | None: Array of 2D landmark positions or None if no landmarks are detected.
"""
def read_landmark_positions_2d(
results: Any,
image_width: int,
image_height: int,
) -> npt.NDArray[np.float32] | None:
if results.pose_landmarks is None:
return None
else:
# Extract normalized landmark positions and scale them to image dimensions
normalized_landmarks = [results.pose_landmarks.landmark[lm] for lm in mp.solutions.pose.PoseLandmark]
return np.array([(image_width * lm.x, image_height * lm.y) for lm in normalized_landmarks])

"""
Read 3D landmark positions from Mediapipe Pose results.

Args:
results (Any): Mediapipe Pose results.

Returns:
np.array | None: Array of 3D landmark positions or None if no landmarks are detected.
"""
def read_landmark_positions_3d(
results: Any,
) -> npt.NDArray[np.float32] | None:
if results.pose_landmarks is None:
return None
else:
# Extract 3D landmark positions
landmarks = [results.pose_world_landmarks.landmark[lm] for lm in mp.solutions.pose.PoseLandmark]
return np.array([(lm.x, lm.y, lm.z) for lm in landmarks])

"""
Track and analyze pose from an input image.

Args:
image_path (str): Path to the input image.
"""
def track_pose(image_path: str) -> None:
# Read the image, convert color to RGB
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Create a Pose model instance
pose_detector = mp.solutions.pose.Pose(static_image_mode=True)

# Process the image to obtain pose landmarks
results = pose_detector.process(image)
h, w, _ = image.shape

# Read 2D and 3D landmark positions
landmark_positions_2d = read_landmark_positions_2d(results, w, h)
landmark_positions_3d = read_landmark_positions_3d(results)

Volver a ejecutar el visor | Imagen vía Volver a ejecutar documentos [2]

Repetición Sirve como herramienta de visualización para datos multimodales. A través de Volver a ejecutar el visor, puede crear diseños, personalizar visualizaciones e interactuar con sus datos. El resto de esta sección detalla cómo puede registrar y presentar datos usando Rerun SDK para visualizarlos dentro del Rerun Viewer.

Pose modelo Landmarker | Imagen vía Guía de detección de puntos de referencia de Pose por Google [1]

Tanto en puntos 2D como 3D, especificar las conexiones entre puntos es esencial. La definición de estas conexiones genera automáticamente líneas entre ellas. Usando la información proporcionada por MediaPipe, puede obtener las conexiones de los puntos de pose del POSE_CONNECTIONS establecer y luego configurarlos como conexiones de puntos clave usando Contexto de anotación.

rr.log(
"/",
rr.AnnotationContext(
rr.ClassDescription(
info=rr.AnnotationInfo(id=0, label="Person"),
keypoint_annotations=[rr.AnnotationInfo(id=lm.value, label=lm.name) for lm in mp_pose.PoseLandmark],
keypoint_connections=mp_pose.POSE_CONNECTIONS,
)
),
timeless=True,
)

Coordenadas de imagen: posiciones 2D

Visualizando la pose humana como puntos 2D | Imagen por autor

Visualizar los puntos de referencia de las poses del cuerpo en el vídeo parece ser una buena opción. Para lograrlo, debe seguir la documentación de repetición de Entidades y Componentes. La jerarquía de rutas de entidades La página describe cómo registrar múltiples componentes en la misma entidad. Por ejemplo, puede crear la entidad ‘video’ e incluir los componentes ‘video/rgb’ para el video y ‘video/pose’ para la pose del cuerpo. Si pretendes utilizar eso para un vídeo, necesitas el concepto de Líneas de tiempo. Cada cuadro se puede asociar con los datos apropiados.

Aquí hay una función que puede visualizar los puntos 2D en el video:

def track_pose_2d(video_path: str) -> None:
mp_pose = mp.solutions.pose

with closing(VideoSource(video_path)) as video_source, mp_pose.Pose() as pose:
for idx, bgr_frame in enumerate(video_source.stream_bgr()):
if max_frame_count is not None and idx >= max_frame_count:
break

rgb = cv2.cvtColor(bgr_frame.data, cv2.COLOR_BGR2RGB)

# Associate frame with the data
rr.set_time_seconds("time", bgr_frame.time)
rr.set_time_sequence("frame_idx", bgr_frame.idx)

# Present the video
rr.log("video/rgb", rr.Image(rgb).compress(jpeg_quality=75))

# Get the prediction results
results = pose.process(rgb)
h, w, _ = rgb.shape

# Log 2d points to 'video' entity
landmark_positions_2d = read_landmark_positions_2d(results, w, h)
if landmark_positions_2d is not None:
rr.log(
"video/pose/points",
rr.Points2D(landmark_positions_2d, class_ids=0, keypoint_ids=mp_pose.PoseLandmark),
)

Coordenadas mundiales 3D: puntos 3D

Visualizando la pose humana como puntos 3D | Imagen por autor

¿Por qué conformarse con puntos 2D cuando tienes puntos 3D? Cree una nueva entidad, asígnele el nombre “Persona” y registre los puntos 3D. ¡Está hecho! Acabas de crear una presentación en 3D de la pose del cuerpo humano.

Aquí se explica cómo hacerlo:

def track_pose_3d(video_path: str, *, segment: bool, max_frame_count: int | None) -> None:
mp_pose = mp.solutions.pose

rr.log("person", rr.ViewCoordinates.RIGHT_HAND_Y_DOWN, timeless=True)

with closing(VideoSource(video_path)) as video_source, mp_pose.Pose() as pose:
for idx, bgr_frame in enumerate(video_source.stream_bgr()):
if max_frame_count is not None and idx >= max_frame_count:
break

rgb = cv2.cvtColor(bgr_frame.data, cv2.COLOR_BGR2RGB)

# Associate frame with the data
rr.set_time_seconds("time", bgr_frame.time)
rr.set_time_sequence("frame_idx", bgr_frame.idx)

# Present the video
rr.log("video/rgb", rr.Image(rgb).compress(jpeg_quality=75))

# Get the prediction results
results = pose.process(rgb)
h, w, _ = rgb.shape

# New entity "Person" for the 3D presentation
landmark_positions_3d = read_landmark_positions_3d(results)
if landmark_positions_3d is not None:
rr.log(
"person/pose/points",
rr.Points3D(landmark_positions_3d, class_ids=0, keypoint_ids=mp_pose.PoseLandmark),
)

El tutorial se centra en las partes principales del ejemplo de Seguimiento de postura humana. Para aquellos que prefieren un enfoque práctico, el código fuente completo de este ejemplo está disponible en GitHub. Siéntase libre de explorar, modificar y comprender el funcionamiento interno de la implementación.

1. Comprime la imagen para mayor eficiencia.

Puede aumentar la velocidad general del procedimiento comprimiendo las imágenes registradas:

rr.log(
"video",
rr.Image(img).compress(jpeg_quality=75)
)

2. Limitar el uso de la memoria

Si está registrando más datos de los que pueden caber en su RAM, comenzará a eliminar los datos antiguos. El límite predeterminado es el 75% de la RAM del sistema. Si desea aumentar eso, puede usar el argumento de la línea de comando: límite de memoria. Puede encontrar más información sobre los límites de memoria en Rerun’s Cómo limitar el uso de la memoria página.

3. Personalice las visualizaciones según sus necesidades

Personalizar el visor de repetición | Imagen por autor

Si este artículo le resultó útil y revelador, ¡hay más!

Artículos similares:

Comparto regularmente tutoriales sobre visualización para visión por computadora y robótica. ¡Sígueme para futuras actualizaciones!

Además, puedes encontrarme en LinkedIn.

[1] Guía de detección de puntos de referencia de Pose por GooglePartes de esta página se reproducen a partir del trabajo creado y compartido por google y utilizado según los términos descritos en el Licencia de atribución Creative Commons 4.0.

[2] Volver a ejecutar documentos por Repetición bajo licencia MIT