tutoriales.com

Estimación de Pose Humana en 2D con OpenPose: Un Tutorial Práctico con Python y OpenCV

Este tutorial te guiará paso a paso en la estimación de pose humana en 2D utilizando OpenPose, una de las librerías más robustas y precisas. Exploraremos desde los conceptos teóricos hasta la implementación práctica con Python y OpenCV, permitiéndote detectar los puntos clave del cuerpo en imágenes y vídeos.

Intermedio15 min de lectura7 views
Reportar error

La estimación de pose humana es una rama fascinante de la visión artificial que se centra en la identificación y localización de puntos clave (keypoints) del cuerpo humano, como codos, rodillas, muñecas, cuello, etc., en una imagen o secuencia de vídeo. Esta tecnología tiene un sinfín de aplicaciones, desde el análisis deportivo y la realidad aumentada hasta la interacción humano-ordenador y la seguridad.

En este tutorial, nos sumergiremos en OpenPose, un sistema de código abierto pionero y altamente efectivo para la estimación de pose en múltiples personas en tiempo real. Desarrollado por el laboratorio de Percepción de Carnegie Mellon University, OpenPose se ha consolidado como una herramienta fundamental en el campo, ofreciendo una gran precisión y flexibilidad.

🚀 ¿Qué es la Estimación de Pose Humana?

La estimación de pose humana consiste en predecir la configuración del cuerpo de una o varias personas. En su forma 2D, esto significa localizar coordenadas (x, y) para cada keypoint corporal detectado. Imagina que el sistema traza un esqueleto virtual sobre la persona en la imagen. Estos puntos clave, una vez detectados, se conectan para formar lo que conocemos como el esqueleto de la pose.

Tipos de Estimación de Pose

Existen principalmente dos tipos de estimación de pose:

  • Estimación de Pose 2D: Determina las coordenadas (x, y) de los puntos clave del cuerpo en un plano bidimensional, es decir, sobre la propia imagen. Es lo que abordaremos en este tutorial.
  • Estimación de Pose 3D: Va un paso más allá, prediciendo las coordenadas (x, y, z) de los puntos clave, lo que permite reconstruir la pose en un espacio tridimensional. Esto es más complejo y requiere técnicas adicionales, a menudo usando múltiples cámaras o modelos generativos.
💡 Consejo: La estimación de pose 2D es un excelente punto de partida para comprender los fundamentos antes de adentrarse en la complejidad de la pose 3D. Muchas aplicaciones prácticas pueden resolverse eficientemente con pose 2D.

Aplicaciones Comunes de la Estimación de Pose

La versatilidad de la estimación de pose la hace invaluable en diversas industrias:

  • Análisis Deportivo: Monitoreo de la forma física, corrección de técnicas en golf, gimnasia o natación.
  • Realidad Aumentada (RA): Superposición de objetos virtuales que interactúan con el movimiento corporal.
  • Videojuegos: Control de personajes mediante gestos o movimientos corporales.
  • Robótica: Robots que imitan movimientos humanos o interactúan con personas de forma natural.
  • Salud y Rehabilitación: Seguimiento de ejercicios de rehabilitación, análisis de la marcha.
  • Seguridad y Vigilancia: Detección de actividades sospechosas o caídas.
  • Interacción Humano-Ordenador: Sistemas que responden a gestos y lenguaje corporal.

💡 ¿Por Qué OpenPose? Fundamentos y Arquitectura

OpenPose es reconocido por su precisión y capacidad para detectar poses en múltiples personas en una misma imagen, incluso en escenas concurridas. Su arquitectura se basa en Redes Neuronales Convolucionales (CNNs) profundas y una estrategia ingeniosa para asociar los puntos clave detectados con individuos específicos.

La Innovación de OpenPose: Parte Affinity Fields (PAFs)

La clave de OpenPose reside en el uso de Part Affinity Fields (PAFs). Mientras que otros métodos simplemente detectan puntos clave y luego intentan agruparlos, OpenPose predice dos tipos de mapas en paralelo:

  1. Mapas de Confianza (Confidence Maps): Estos mapas indican la probabilidad de que un keypoint corporal específico (como un codo o una muñeca) se encuentre en una determinada ubicación de la imagen.
  2. Part Affinity Fields (PAFs): Estos son campos vectoriales 2D que codifican la dirección y magnitud de la conexión entre pares de keypoints (por ejemplo, entre el hombro y el codo). Los PAFs son cruciales para asociar correctamente los puntos clave de cada persona, incluso cuando hay varias personas solapándose en la imagen.
📌 Nota: Los PAFs permiten a OpenPose resolver el problema de la *asociación de partes*, que es la tarea de agrupar correctamente los puntos clave de cada persona individual en una escena con múltiples individuos.
Imagen de Entrada Confidence Maps (S) Detección de puntos clave Part Affinity Fields (L) Conexiones entre miembros Post-Procesado Asociación (Matching) Poses Humanas Finales

El Proceso en OpenPose (Simplificado)

El flujo de trabajo de OpenPose se puede resumir en los siguientes pasos:

  1. Extracción de Características: La imagen de entrada es procesada por una red neuronal convolucional base (como VGG) para extraer características de bajo nivel.
  2. Ramas Paralelas: Estas características se alimentan a dos ramas de red neuronales paralelas:
    • Una rama predice los mapas de confianza para cada keypoint (por ejemplo, cabeza, hombro, codo, muñeca, etc.).
    • La otra rama predice los Part Affinity Fields (PAFs) para cada par de keypoints conectados (por ejemplo, hombro a codo, codo a muñeca).
  3. Post-procesamiento: Un algoritmo de post-procesamiento utiliza los mapas de confianza y los PAFs para ensamblar las poses. Este algoritmo recorre los PAFs para conectar los keypoints de manera que formen esqueletos coherentes para cada persona detectada.

Este enfoque permite a OpenPose ser muy robusto ante oclusiones parciales y complejas interacciones entre personas.


🛠️ Configuración del Entorno: Preparando OpenPose

Antes de sumergirnos en el código, necesitamos configurar nuestro entorno. Aunque OpenPose puede compilarse desde la fuente para un rendimiento óptimo con GPU, para este tutorial utilizaremos una versión pre-entrenada disponible a través de OpenCV, lo que simplifica enormemente la instalación.

Requisitos Previos

Asegúrate de tener instalados los siguientes componentes:

  • Python 3.x: Se recomienda una versión reciente.
  • pip: El gestor de paquetes de Python.
  • OpenCV: La librería de visión artificial.
  • NumPy: Para operaciones numéricas.

Puedes instalar o actualizar las librerías necesarias con el siguiente comando:

pip install opencv-python numpy

Descarga de Modelos Pre-entrenados

OpenPose utiliza modelos de redes neuronales profundas que requieren archivos de peso (weights) pre-entrenados. Para simplificar, descargaremos los modelos necesarios que OpenCV puede cargar. En particular, usaremos el modelo COCO (Common Objects in Context) que detecta 18 keypoints.

Puedes descargar estos modelos desde el repositorio de OpenCV o buscar un script que lo haga automáticamente. Para este tutorial, asumiremos que los has descargado y colocado en una carpeta llamada models en tu directorio de trabajo.

¿Dónde encontrar los modelos de OpenPose para OpenCV? Los modelos pre-entrenados para OpenPose en OpenCV suelen estar disponibles en los siguientes enlaces o repositorios:
  • Protoxt (.prototxt): Define la arquitectura de la red neuronal.
    • https://raw.githubusercontent.com/opencv/opencv_extra/master/testdata/dnn/openpose_pose_coco.prototxt
  • Caffemodel (.caffemodel): Contiene los pesos pre-entrenados de la red.
    • http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz (este es para otro modelo, busca específicamente pose_iter_440000.caffemodel o similar para OpenPose)

Una forma más directa es buscar los modelos en el repositorio de OpenCV en GitHub o usar un script auxiliar. Para el modelo COCO de 18 puntos, necesitarás:

  • pose_deploy_linevec.prototxt (o similar, para la arquitectura)
  • pose_iter_440000.caffemodel (para los pesos)

Crea una carpeta llamada models y guarda ambos archivos ahí.

Estructura de Archivos Recomendada

. 
├── my_openpose_app.py
└── models/
    ├── pose_deploy_linevec.prototxt
    └── pose_iter_440000.caffemodel

📝 Implementación Práctica: Estimación de Pose en Imágenes

Ahora que tenemos nuestro entorno listo, vamos a escribir el código para realizar la estimación de pose en una imagen.

Paso 1: Importar Librerías y Cargar Modelos

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Rutas a los modelos
protoFile = "models/pose_deploy_linevec.prototxt"
weightsFile = "models/pose_iter_440000.caffemodel"

# Número de puntos clave para el modelo COCO
nPoints = 18

# Mapeo de puntos clave (para COCO)
POSE_PAIRS = [
    [1,0],[1,2],[1,5],[2,3],[3,4],[5,6],[6,7],[1,8],[8,9],[9,10],[1,11],[11,12],[12,13],[0,14],[0,15],[14,16],[15,17]
]

# Cargamos la red neuronal
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
print("Modelos de OpenPose cargados exitosamente.")
🔥 Importante: Asegúrate de que los archivos `pose_deploy_linevec.prototxt` y `pose_iter_440000.caffemodel` estén en la carpeta `models` dentro de tu directorio de trabajo. De lo contrario, el código fallará al intentar cargarlos.

Paso 2: Pre-procesar la Imagen de Entrada

Las redes neuronales esperan las imágenes en un formato específico (conocido como blob). Necesitamos redimensionar la imagen y normalizar sus valores.

# Cargar una imagen de ejemplo
image_path = "test_image.jpg" # Asegúrate de tener una imagen llamada test_image.jpg
frame = cv2.imread(image_path)

# Redimensionar la imagen para el procesamiento de OpenPose (opcional, mejora el rendimiento)
frameWidth = frame.shape[1]
frameHeight = frame.shape[0]

inWidth = 368 # Ancho de entrada recomendado para OpenPose
inHeight = 368 # Alto de entrada recomendado para OpenPose

# Crear el blob de la imagen
# Los valores son: escalar imagen, tamaño (ancho, alto), media de resta (R,G,B), swap azul y rojo, cortar imagen
# El factor de escala 1.0/255 normaliza los píxeles a [0, 1]
# La media de resta es comúnmente usada para modelos entrenados con VGG
inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight), (124.96, 115.90, 106.13), swapRB=True, crop=False)

# Establecer la entrada de la red
net.setInput(inpBlob)

Paso 3: Ejecutar la Inferencia y Obtener Salida

Ahora pasamos el blob a la red neuronal y obtenemos los mapas de confianza y los PAFs.

# Realizar la inferencia
output = net.forward()
print(f"Dimensiones de la salida de la red: {output.shape}") # (1, nPoints, H_out, W_out)

# La salida contiene los mapas de confianza y los PAFs
# Los primeros nPoints canales corresponden a los confidence maps de los keypoints
# Los canales restantes corresponden a los Part Affinity Fields

Paso 4: Procesar la Salida y Dibujar la Pose

Extraeremos los puntos clave de los mapas de confianza y luego los conectaremos usando los POSE_PAIRS.

H = output.shape[2] # Altura de los mapas de salida
W = output.shape[3] # Ancho de los mapas de salida

# Escalar los puntos clave de vuelta a las dimensiones originales de la imagen
points = []
for i in range(nPoints):
    # Extraer el mapa de confianza para el keypoint actual
    probMap = output[0, i, :, :]

    # Encontrar la ubicación del pico de confianza (donde hay mayor probabilidad)
    minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
    
    # Escalar las coordenadas del punto para que coincidan con la imagen original
    x = (frameWidth * point[0]) / W
    y = (frameHeight * point[1]) / H

    # Añadir el punto si la probabilidad es lo suficientemente alta
    # y asegurarnos de que el punto esté dentro de los límites de la imagen
    if prob > 0.1: # Umbral de confianza, ajusta según sea necesario
        points.append((int(x), int(y)))
        cv2.circle(frame, (int(x), int(y)), 8, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
        cv2.putText(frame, str(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2, lineType=cv2.LINE_AA)
    else:
        points.append(None)

# Dibujar las conexiones (esqueleto)
for pair in POSE_PAIRS:
    partA = pair[0]
    partB = pair[1]

    if points[partA] and points[partB]:
        cv2.line(frame, points[partA], points[partB], (0, 255, 255), 3, lineType=cv2.LINE_AA)
        cv2.circle(frame, points[partA], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
        cv2.circle(frame, points[partB], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)

# Mostrar la imagen resultante
plt.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.title('Estimación de Pose con OpenPose')
plt.show()

# Opcional: Guardar la imagen de salida
cv2.imwrite("output_pose.jpg", frame)

Código Completo para una Imagen

import cv2
import numpy as np
import matplotlib.pyplot as plt

# --- Configuración de OpenPose ---
protoFile = "models/pose_deploy_linevec.prototxt"
weightsFile = "models/pose_iter_440000.caffemodel"

nPoints = 18 # Número de puntos clave para el modelo COCO

# Pares de puntos clave para dibujar el esqueleto (modelo COCO)
POSE_PAIRS = [
    [1,0],[1,2],[1,5],[2,3],[3,4],[5,6],[6,7],[1,8],[8,9],[9,10],[1,11],[11,12],[12,13],[0,14],[0,15],[14,16],[15,17]
]

# Cargar la red neuronal
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
print("Modelos de OpenPose cargados exitosamente.")

# --- Carga y preprocesamiento de la imagen ---
image_path = "test_image.jpg" 
frame = cv2.imread(image_path)

if frame is None:
    print(f"Error: No se pudo cargar la imagen desde {image_path}. Asegúrate de que existe.")
    exit()

frameWidth = frame.shape[1]
frameHeight = frame.shape[0]

inWidth = 368  # Ancho recomendado para OpenPose
inHeight = 368 # Alto recomendado para OpenPose

# Crear el blob de la imagen para la entrada de la red
inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight), (124.96, 115.90, 106.13), swapRB=True, crop=False)

# --- Inferencia de la red neuronal ---
net.setInput(inpBlob)
output = net.forward()

H = output.shape[2] # Altura de los mapas de salida
W = output.shape[3] # Ancho de los mapas de salida

# --- Post-procesamiento y dibujo de la pose ---
points = []
for i in range(nPoints):
    probMap = output[0, i, :, :]
    minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
    
    x = (frameWidth * point[0]) / W
    y = (frameHeight * point[1]) / H

    if prob > 0.1: # Umbral de confianza
        points.append((int(x), int(y)))
        # Dibujar un círculo en el keypoint
        cv2.circle(frame, (int(x), int(y)), 8, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
        # Opcional: Poner el número del keypoint
        # cv2.putText(frame, str(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2, lineType=cv2.LINE_AA)
    else:
        points.append(None)

# Dibujar las conexiones del esqueleto
for pair in POSE_PAIRS:
    partA = pair[0]
    partB = pair[1]

    if points[partA] and points[partB]:
        cv2.line(frame, points[partA], points[partB], (0, 255, 255), 3, lineType=cv2.LINE_AA)
        cv2.circle(frame, points[partA], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
        cv2.circle(frame, points[partB], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)

# --- Mostrar y guardar resultados ---
plt.figure(figsize=(10, 8))
plt.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.title('Estimación de Pose con OpenPose')
plt.show()

cv2.imwrite("output_pose.jpg", frame)
print("Resultado guardado como output_pose.jpg")
💡 Consejo: Para probar este código, descarga una imagen de una persona y guárdala como `test_image.jpg` en el mismo directorio que tu script.

🎥 Estimación de Pose en Vídeo o Cámara en Vivo

La extensión a vídeos o transmisiones de cámara en vivo es bastante directa, ya que un vídeo es simplemente una secuencia de imágenes (frames).

import cv2
import numpy as np

# --- Configuración de OpenPose ---
protoFile = "models/pose_deploy_linevec.prototxt"
weightsFile = "models/pose_iter_440000.caffemodel"

nPoints = 18 # Número de puntos clave para el modelo COCO

POSE_PAIRS = [
    [1,0],[1,2],[1,5],[2,3],[3,4],[5,6],[6,7],[1,8],[8,9],[9,10],[1,11],[11,12],[12,13],[0,14],[0,15],[14,16],[15,17]
]

net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
print("Modelos de OpenPose cargados exitosamente.")

# --- Configuración para video/cámara ---
# Para webcam, usa 0. Para archivo de video, usa "nombre_video.mp4"
cap = cv2.VideoCapture(0) 

if not cap.isOpened():
    print("Error: No se pudo abrir la fuente de video.")
    exit()

# Opcional: Configurar el tamaño de la ventana de visualización
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

# Parámetros de entrada para la red
inWidth = 368
inHeight = 368
confThreshold = 0.1 # Umbral de confianza para los keypoints

while cv2.waitKey(1) < 0:
    hasFrame, frame = cap.read()

    if not hasFrame:
        cv2.waitKey() # Esperar una tecla si el video termina
        break

    frameWidth = frame.shape[1]
    frameHeight = frame.shape[0]

    inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight), (124.96, 115.90, 106.13), swapRB=True, crop=False)
    net.setInput(inpBlob)
    output = net.forward()

    H = output.shape[2]
    W = output.shape[3]

    points = []
    for i in range(nPoints):
        probMap = output[0, i, :, :]
        minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
        
        x = (frameWidth * point[0]) / W
        y = (frameHeight * point[1]) / H

        if prob > confThreshold:
            points.append((int(x), int(y)))
            cv2.circle(frame, (int(x), int(y)), 8, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
            # cv2.putText(frame, str(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2, lineType=cv2.LINE_AA)
        else:
            points.append(None)

    for pair in POSE_PAIRS:
        partA = pair[0]
        partB = pair[1]

        if points[partA] and points[partB]:
            cv2.line(frame, points[partA], points[partB], (0, 255, 255), 3, lineType=cv2.LINE_AA)
            cv2.circle(frame, points[partA], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
            cv2.circle(frame, points[partB], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
    
    # Mostrar el frame procesado
    cv2.imshow('OpenPose Live Demo', frame)

# Liberar el objeto de captura y cerrar ventanas
cap.release()
cv2.destroyAllWindows()
print("Demostración de OpenPose en vivo finalizada.")
⚠️ Advertencia: La ejecución de OpenPose en tiempo real con una CPU puede ser lenta. Para un rendimiento óptimo, se recomienda una GPU con CUDA y una compilación personalizada de OpenCV con soporte CUDA o una instalación completa de OpenPose desde la fuente.

📈 Optimización y Consideraciones de Rendimiento

La estimación de pose, especialmente con modelos profundos como OpenPose, puede ser computacionalmente intensiva. Aquí hay algunas consideraciones para mejorar el rendimiento:

Tamaño de la Imagen de Entrada

Reducir el inWidth y inHeight del blob de entrada (inpBlob) puede acelerar significativamente la inferencia a costa de una posible pérdida de precisión, especialmente para detectar personas pequeñas o keypoints sutiles.

Más Pequeño = Más Rápido

Hardware

  • GPU: Como se mencionó, una tarjeta gráfica con soporte CUDA es crucial para obtener velocidades cercanas al tiempo real. La versión de OpenCV que estamos usando para DNN puede utilizar la GPU si ha sido compilada con los módulos adecuados y si tu sistema tiene CUDA configurado.
  • CPU: Si solo tienes CPU, experimenta con tamaños de entrada más pequeños y considera ejecutar el código en una máquina con un procesador potente.

Modelos Ligeros

OpenPose también ofrece modelos más ligeros (por ejemplo, basados en Mobilenet) que son más rápidos pero pueden ser menos precisos que el modelo VGG-19 COCO que usamos aquí. Si el rendimiento es crítico, busca y utiliza estos modelos alternativos.

Umbral de Confianza

El confThreshold (prob > 0.1 en nuestro código) determina qué tan seguro debe estar el modelo para considerar un keypoint como válido. Aumentar este valor puede reducir los falsos positivos pero también puede omitir keypoints reales en escenas complejas o con poca visibilidad.

🔮 Más allá de la Detección: Análisis de Pose y Aplicaciones Avanzadas

Una vez que tienes los puntos clave, el verdadero poder de la estimación de pose se desbloquea al analizar esos datos. Puedes hacer cosas como:

  • Cálculo de Ángulos Corporales: Calcular el ángulo del codo, la rodilla, etc., para análisis de movimiento.
  • Detección de Actividad: Identificar acciones como caminar, correr, sentarse, levantar un brazo.
  • Seguimiento de Pose (Pose Tracking): Asociar las poses detectadas en frames consecutivos con la misma persona para un seguimiento a lo largo del tiempo.
  • Control por Gestos: Utilizar la posición de las manos o el cuerpo para controlar aplicaciones.
  • Biomecánica y Ergonomía: Análisis detallado de la postura y el movimiento para prevenir lesiones o mejorar el rendimiento.

Ejemplo: Cálculo de Ángulo de Brazo

Imagina que quieres calcular el ángulo del brazo en el codo. Necesitarías los keypoints del hombro, el codo y la muñeca.

Ángulo Hombro (P1) Codo (P2) Muñeca (P3)

Si points[5] es el hombro izquierdo, points[6] el codo izquierdo y points[7] la muñeca izquierda (según el mapeo COCO de 18 puntos):

def calculate_angle(p1, p2, p3):
    # Calcula el ángulo entre tres puntos (p1-p2-p3) donde p2 es el vértice
    # p1, p2, p3 son tuplas (x, y)
    if p1 is None or p2 is None or p3 is None:
        return None

    p1 = np.array(p1)
    p2 = np.array(p2)
    p3 = np.array(p3)

    # Vectores formados por los puntos
    v1 = p1 - p2
    v2 = p3 - p2

    # Calcular el producto punto y las magnitudes de los vectores
    dot_product = np.dot(v1, v2)
    magnitude_v1 = np.linalg.norm(v1)
    magnitude_v2 = np.linalg.norm(v2)

    if magnitude_v1 == 0 or magnitude_v2 == 0:
        return None

    # Calcular el coseno del ángulo y luego el ángulo en grados
    angle_rad = np.arccos(dot_product / (magnitude_v1 * magnitude_v2))
    angle_deg = np.degrees(angle_rad)

    return angle_deg

# Después de detectar los points:
# Por ejemplo, para el codo izquierdo:
shoulder_l = points[5] # Keypoint 5: Hombro izquierdo
elbow_l = points[6]    # Keypoint 6: Codo izquierdo
wrist_l = points[7]    # Keypoint 7: Muñeca izquierda

elbow_angle = calculate_angle(shoulder_l, elbow_l, wrist_l)

if elbow_angle is not None:
    print(f"Ángulo del codo izquierdo: {elbow_angle:.2f} grados")
    # Puedes dibujar este ángulo en la imagen también

🔚 Conclusión

La estimación de pose humana con OpenPose es una herramienta potente y versátil que abre la puerta a innumerables aplicaciones en el campo de la visión artificial. A lo largo de este tutorial, hemos cubierto desde los fundamentos teóricos de OpenPose y su innovadora arquitectura de PAFs hasta una implementación práctica con Python y OpenCV para imágenes y vídeo en tiempo real.

Has aprendido a configurar tu entorno, cargar los modelos pre-entrenados y procesar las imágenes para visualizar los keypoints y el esqueleto humano. Aunque el rendimiento puede ser una consideración importante, especialmente sin una GPU, los conceptos y la implementación aquí presentados te proporcionan una base sólida para explorar proyectos más avanzados.

Te animo a experimentar con diferentes imágenes y vídeos, a ajustar el umbral de confianza y a explorar las posibilidades de análisis de pose para tus propios proyectos. ¡El mundo de la visión artificial está lleno de oportunidades para la creatividad y la innovación!

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!