Con la API de ML Kit Pose Detection, puedes obtener interpretaciones significativas de una pose al comprobar las posiciones relativas de varias partes del cuerpo. Esta página demuestra algunos ejemplos.
Clasificación de poses y recuento de repeticiones con el algoritmo k-NN
Una de las aplicaciones más comunes de la detección de poses es el seguimiento de fitness. Crear un clasificador de poses que reconozca poses y recuentos específicos de la aptitud física las repeticiones pueden ser una tarea difícil para los desarrolladores.
En esta sección, describimos cómo creamos una pose personalizada clasificador con MediaPipe Colab demostrar un clasificador funcional en nuestra app de ejemplo del ML Kit.
Si no conoces Google Colaboratory, consulta la guía de introducción.
Para reconocer las poses, usamos el algoritmo de k-vecinos más cercanos (k-NN) porque es simple y fácil de usar. El algoritmo determina la clase del objeto según la muestras más cercanas en el conjunto de entrenamiento.
Sigue estos pasos para compilar y entrenar el reconocedor:
1. Recopila muestras de imágenes
Recopilamos muestras de imágenes de los ejercicios de destino de varias fuentes. Elegimos algunas cientos de imágenes para cada ejercicio, como las posiciones "arriba" y "abajo" para las flexiones. Es importante recopilar muestras que abarquen diferentes ángulos de cámara, condiciones ambientales, formas del cuerpo y variaciones de ejercicio.
2. Ejecuta la detección de poses en las imágenes de muestra
Esto produce un conjunto de puntos de referencia de pose que se usarán para el entrenamiento. No que les interese la detección de poses, ya que entrenaremos nuestro propio modelo en el próximo paso.
El algoritmo k-NN que elegimos para la clasificación de poses personalizada requiere un representación de vector de atributos para cada muestra y una métrica para calcular la distancia entre dos vectores para encontrar el objetivo más cercano a la muestra de la postura. Esto significa que debemos convertir los puntos de referencia de las poses que acabamos de obtener.
Para convertir los puntos de referencia de la pose en un vector de características, usamos las distancias entre pares entre listas predefinidas de articulaciones de pose, como la distancia entre la muñeca y el hombro, el tobillo y la cadera, y las muñecas izquierda y derecha. Dado que la escala de las imágenes pueden variar, normalizamos las poses para que tuvieran el mismo tamaño de torso y el mismo torso. la orientación antes de convertir los puntos de referencia.
3. Entrena el modelo y cuenta las repeticiones
Usamos MediaPipe Colab para acceder al código del clasificador y entrenar el modelo.
Para contar las repeticiones, usamos otro algoritmo de Colab para supervisar el umbral de probabilidad de una posición de pose objetivo. Por ejemplo:
- Cuando la probabilidad de que "caiga" la clase pose pasa un umbral determinado para primera vez, el algoritmo marca que el botón "down" se ingresó la clase pose.
- Cuando la probabilidad cae por debajo del umbral, el algoritmo marca que se salió de la clase de postura “abajo” y aumenta el contador.
4. Realiza la integración en la app de inicio rápido del Kit de AA
El Colab anterior produce un archivo CSV que puedes propagar con todos tus ejemplos de poses. En esta sección, aprenderás a integrar tu archivo CSV con la App de inicio rápido para Android de ML Kit para ver la clasificación de poses personalizada en tiempo real.
Prueba la clasificación de poses con muestras incluidas en la app de inicio rápido
- Obtén el proyecto de la app de inicio rápido para Android del Kit de AA. desde GitHub y asegúrate de que se compile y se ejecute bien.
- Ve a
LivePreviewActivity
y habilita la detección de posesRun classification
en la página Configuración. Ahora deberías poder clasificar flexiones y sentadillas.
Agrega tu propio archivo CSV
- Agrega el archivo CSV a la carpeta de recursos de la app.
- En PoseClassifierProcessor, actualiza las variables
POSE_SAMPLES_FILE
yPOSE_CLASSES
para que coincidan con tu archivo CSV y las muestras de poses. - Compila y ejecuta la app.
Ten en cuenta que es posible que la clasificación no funcione bien si no hay suficientes muestras. Por lo general, necesitas alrededor de 100 muestras por clase de pose.
Para obtener más información y probarlo tú mismo, consulta el MediaPipe Colab y la guía de clasificación de MediaPipe.
Cómo reconocer gestos simples calculando la distancia de los puntos de referencia
Cuando dos o más lugares de interés están cerca entre sí, se pueden usar para reconocer gestos. Por ejemplo, cuando el punto de referencia de uno o más dedos de una mano está cerca del punto de referencia de la nariz, puedes inferir que es probable que el usuario se esté tocando la cara.
Reconoce una postura de yoga con una heurística de ángulos
Para identificar una postura de yoga, puedes calcular los ángulos de varias articulaciones. Para ejemplo, la Figura 2 a continuación muestra la postura de yoga del Guerrero II. Los ángulos aproximados que identifican esta pose están escritas en:
Esta pose puede describirse como la siguiente combinación de cuerpo aproximado ángulos parciales:
- Ángulo de 90 grados en ambos hombros
- 180 grados en ambos codos
- Ángulo de 90 grados en la pierna delantera y la cintura
- Ángulo de 180 grados en la rodilla de atrás
- Ángulo de 135 grados en la cintura
Puedes usar los puntos de referencia de la pose para calcular estos ángulos. Por ejemplo, el ángulo en la pierna delantera derecha y la cintura, está el ángulo entre la línea de la derecha hombro a la cadera derecha y la línea desde la cadera derecha a la rodilla derecha.
Una vez que hayas calculado todos los ángulos necesarios para identificar la pose, puedes comprobar para ver si hay una coincidencia, en cuyo caso reconoces la pose.
En el siguiente fragmento de código, se muestra cómo usar las coordenadas X e Y para calcular el ángulo entre dos partes del cuerpo. Este enfoque de clasificación tiene algunas limitaciones. Si solo se verifican X e Y, los ángulos calculados varían según el ángulo entre el sujeto y la cámara. Obtendrás las obtener mejores resultados con una imagen plana, recta y de frente. También puedes intentar extender este algoritmo con la coordenada Z y ver si tiene un mejor rendimiento para tu caso de uso.
Cálculo de ángulos de puntos de referencia en Android
El siguiente método calcula el ángulo entre tres puntos de referencia. Garantiza que el ángulo devuelto esté entre 0 y 180 grados.
Kotlin
fun getAngle(firstPoint: PoseLandmark, midPoint: PoseLandmark, lastPoint: PoseLandmark): Double { var result = Math.toDegrees(atan2(lastPoint.getPosition().y - midPoint.getPosition().y, lastPoint.getPosition().x - midPoint.getPosition().x) - atan2(firstPoint.getPosition().y - midPoint.getPosition().y, firstPoint.getPosition().x - midPoint.getPosition().x)) result = Math.abs(result) // Angle should never be negative if (result > 180) { result = 360.0 - result // Always get the acute representation of the angle } return result }
Java
static double getAngle(PoseLandmark firstPoint, PoseLandmark midPoint, PoseLandmark lastPoint) { double result = Math.toDegrees( atan2(lastPoint.getPosition().y - midPoint.getPosition().y, lastPoint.getPosition().x - midPoint.getPosition().x) - atan2(firstPoint.getPosition().y - midPoint.getPosition().y, firstPoint.getPosition().x - midPoint.getPosition().x)); result = Math.abs(result); // Angle should never be negative if (result > 180) { result = (360.0 - result); // Always get the acute representation of the angle } return result; }
A continuación, te mostramos cómo calcular el ángulo de la cadera derecha:
Kotlin
val rightHipAngle = getAngle( pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE))
Java
double rightHipAngle = getAngle( pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE));
Calcula ángulos de puntos de referencia en iOS
El siguiente método calcula el ángulo entre cualquier tres puntos de referencia. Garantiza que el ángulo que se muestra esté entre 0 y 180 grados.
Swift
func angle( firstLandmark: PoseLandmark, midLandmark: PoseLandmark, lastLandmark: PoseLandmark ) -> CGFloat { let radians: CGFloat = atan2(lastLandmark.position.y - midLandmark.position.y, lastLandmark.position.x - midLandmark.position.x) - atan2(firstLandmark.position.y - midLandmark.position.y, firstLandmark.position.x - midLandmark.position.x) var degrees = radians * 180.0 / .pi degrees = abs(degrees) // Angle should never be negative if degrees > 180.0 { degrees = 360.0 - degrees // Always get the acute representation of the angle } return degrees }
Objective-C
(CGFloat)angleFromFirstLandmark:(MLKPoseLandmark *)firstLandmark midLandmark:(MLKPoseLandmark *)midLandmark lastLandmark:(MLKPoseLandmark *)lastLandmark { CGFloat radians = atan2(lastLandmark.position.y - midLandmark.position.y, lastLandmark.position.x - midLandmark.position.x) - atan2(firstLandmark.position.y - midLandmark.position.y, firstLandmark.position.x - midLandmark.position.x); CGFloat degrees = radians * 180.0 / M_PI; degrees = fabs(degrees); // Angle should never be negative if (degrees > 180.0) { degrees = 360.0 - degrees; // Always get the acute representation of the angle } return degrees; }
A continuación, te mostramos cómo calcular el ángulo de la cadera derecha:
Swift
let rightHipAngle = angle( firstLandmark: pose.landmark(ofType: .rightShoulder), midLandmark: pose.landmark(ofType: .rightHip), lastLandmark: pose.landmark(ofType: .rightKnee))
Objective-C
CGFloat rightHipAngle = [self angleFromFirstLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightShoulder] midLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightHip] lastLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightKnee]];