Opciones de clasificación de poses

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 actividad física. 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 poses, usamos el algoritmo k-vecinos más cercanos (k-NN) porque es sencillo. y fácil de empezar. 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 objetivo de varias fuentes. Mié elegimos unos cientos de imágenes para cada ejercicio, como “up” y "hacia abajo" posiciones para hacer flexiones. Es importante recopilar muestras que abarquen diferentes los ángulos, las condiciones del entorno, las formas del cuerpo y las variaciones del ejercicio.

Figura 1: Posiciones de las flexiones hacia arriba y abajo

2. Ejecuta la detección de poses en las imágenes de muestra

Esto produce un conjunto de puntos de referencia de poses 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 puntos de referencia de poses en un vector de atributos, usamos las distancias en pares entre listas predefinidas de articulaciones de poses, como la distancia entre la muñeca y hombros, tobillos y cadera, y 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, con un torso igual. 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 para entrenar el modelo.

Para contar las repeticiones, usamos otro algoritmo de Colab para supervisar la probabilidad umbral de una posición 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 el “abajo” se salió y el contador aumenta.
Figura 2: Ejemplo de recuento de repeticiones

4. Realiza la integración en la app de inicio rápido del Kit de AA

El Colab anterior genera un archivo CSV que puedes completar con todas tus poses de muestra. 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

Agrega tu propio archivo CSV

  • Agrega el archivo CSV a la carpeta de recursos de la app.
  • En PoseClassifierProcessor, haz lo siguiente: actualiza las variables POSE_SAMPLES_FILE y POSE_CLASSES para que coincidan con tu archivo CSV y 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 unas 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.

Reconocer gestos simples mediante el cálculo de la distancia del punto de referencia

Cuando dos o más puntos de referencia están cerca, se pueden usar para reconocer gestos. Por ejemplo, cuando el punto de referencia de uno o más dedos en una se encuentra cerca del punto de referencia de la nariz, puedes inferir que el usuario está probablemente se toquen la cara.

Figura 3: Interpretar una pose

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:

Figura 4: Poses diferentes en ángulos

Esta pose puede describirse como la siguiente combinación de cuerpo aproximado ángulos parciales:

  • Ángulo de 90 grados a 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 trasera
  • Ángulo de 135 grados en la cintura

Puedes usar los puntos de referencia de las poses 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.

El siguiente fragmento de código demuestra 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. Al verificar solo 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 podrías intenta extender este algoritmo haciendo uso de Coordenada Z y ver si tiene un mejor rendimiento en tu caso de uso.

Cómo calcular á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 en 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 tres puntos de referencia. Garantiza que el ángulo devuelto 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 en 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]];