Options de classification des postures

L'API ML Kit Pose Detection permet d'obtenir des interprétations pertinentes d'une pose en vérifiant les positions relatives des différentes parties du corps. Cette page présente quelques exemples.

Classification et répétition des postures avec l'algorithme k-NN

Le suivi de l'activité physique est l'une des applications les plus courantes de la détection des postures. Créer un classificateur de postures qui reconnaît des postures et des nombres de postures spécifiques les répétitions peut être un exploit difficile pour les développeurs.

Dans cette section, nous décrivons comment nous avons créé une pose personnalisée. classificateur à l'aide de MediaPipe Colab dans notre exemple d'application ML Kit.

Si vous ne connaissez pas Google Colaboratory, veuillez consulter le guide d'introduction.

Pour reconnaître des postures, nous utilisons l'algorithme des k voisins les plus proches (k-NN), car il est simple et facile pour commencer. L'algorithme détermine la classe de l'objet en fonction les échantillons les plus proches de l'ensemble d'entraînement.

Procédez comme suit pour créer et entraîner le programme de reconnaissance:

1. Collecter des exemples d'images

Nous avons collecté des échantillons d'images des exercices cibles à partir de différentes sources. Mer a choisi quelques centaines d'images pour chaque exercice, par exemple « en haut » et "bas" positions pour les pompes. Il est important de collecter des échantillons couvrant plusieurs caméras les angles, les conditions de l'environnement, les formes du corps et les variations d'exercices.

Figure 1 : Positions des pompes haut et bas

2. Exécuter la détection des postures sur les exemples d'images

Cela produit un ensemble de repères de poses à utiliser pour l'entraînement. Nous ne sommes pas intéressé par la détection des poses elle-même, car nous allons entraîner notre propre modèle à l'étape suivante.

L'algorithme k-NN que nous avons choisi pour la classification personnalisée des postures nécessite représentation du vecteur de caractéristiques pour chaque échantillon et métrique à calculer la distance entre deux vecteurs afin de trouver la cible la plus proche de l'échantillon de pose. Cela signifie que nous devons convertir les points de repère de pose que nous venons d'obtenir.

Pour convertir des points de repère de pose en vecteur de caractéristiques, nous utilisons les distances par paire. entre des listes prédéfinies d'articulations de postures, comme la distance entre des poignets de l'épaule, de la cheville et de la hanche, ainsi que des poignets gauche et droit. Puisque l'échelle des images peut varier, nous avons normalisé les postures pour qu'elles aient la même taille de torse et le même torse vertical avant de convertir les points de repère.

3. Entraîner le modèle et compter les répétitions

Nous avons utilisé MediaPipe Colab pour accéder au code du classificateur. entraîner le modèle.

Pour comptabiliser les répétitions, nous avons utilisé un autre algorithme Colab afin de surveiller la probabilité d'une position cible. Exemple :

  • Lorsque la probabilité de l'« arrêt » la classe "pose" dépasse un seuil donné pour la première fois, l'algorithme indique que l'état "en panne" la classe de pose.
  • Lorsque la probabilité passe en dessous du seuil, l'algorithme indique que "bas" la classe "pose" a été quittée et augmente le compteur.
Figure 2 : Exemple de comptage des répétitions

4. Intégrer l'application de démarrage rapide ML Kit

Le Colab ci-dessus génère un fichier CSV dans lequel vous pouvez remplir tous vos paramètres de pose exemples. Dans cette section, vous apprendrez à intégrer votre fichier CSV à l'API Application de démarrage rapide de ML Kit pour Android permettant d'afficher la classification personnalisée des postures en temps réel.

Essayez la classification de postures à l'aide d'exemples regroupés dans l'application de démarrage rapide

  • Obtenez le projet de démarrage rapide de ML Kit pour Android. depuis GitHub pour vous assurer qu'il se crée et fonctionne correctement.
  • Accédez à LivePreviewActivity et activez la détection des postures Run classification dans les paramètres . Vous devriez maintenant être capable de classer les pompes et les squats.

Ajouter votre propre fichier CSV

  • Ajoutez votre fichier CSV au dossier des composants de l'application.
  • Dans PoseClassifierProcessor, modifiez les variables POSE_SAMPLES_FILE et POSE_CLASSES pour qu'elles correspondent CSV et exemples de poses.
  • Créez et exécutez l'application.

Notez que la classification peut ne pas fonctionner correctement si le nombre d'échantillons est insuffisant. En règle générale, vous avez besoin d'environ 100 échantillons par classe de pose.

Pour en savoir plus et essayer par vous-même, consultez MediaPipe Colab et le guide de classification MediaPipe.

Reconnaître des gestes simples en calculant la distance d'un point de repère

Lorsque deux points de repère ou plus sont proches l'un de l'autre, ils peuvent être utilisés pour reconnaître les gestes. Par exemple, lorsque le point de repère d'un ou plusieurs doigts d'un est proche du point de repère du nez, vous pouvez en déduire que l'utilisateur touchant probablement son visage.

Figure 3 : Interpréter une pose

Reconnaître une posture de yoga à l'aide de l'heuristique de l'angle

Vous pouvez identifier une posture de yoga en calculant les angles de différentes articulations. Pour exemple, la figure 2 ci-dessous montre la posture de yoga du Guerrier II. Les angles approximatifs qui identifient cette posture sont écrits dans:

Figure 4 : Diviser une pose en différents angles

Cette pose peut être décrite comme la combinaison suivante de corps approximatifs Angles partiels:

  • Angle de 90 degrés aux deux épaules
  • 180 degrés au niveau des deux coudes
  • Angle de 90 degrés au niveau de la jambe avant et de la taille
  • Angle de 180 degrés au niveau du genou arrière
  • Tour de taille à 135°

Vous pouvez utiliser les points de repère "pose" pour calculer ces angles. Par exemple, l'angle au niveau de la jambe avant droite et la taille correspond à l'angle entre la ligne de droite de l'épaule à la hanche droite, et la ligne reliant la hanche droite au genou droit.

Une fois que vous avez calculé tous les angles nécessaires pour identifier la pose, vous pouvez vérifier pour voir s'il y a une correspondance, auquel cas vous avez reconnu la pose.

L'extrait de code ci-dessous montre comment utiliser les coordonnées X et Y pour calculer l'angle entre deux parties du corps. Cette approche de la classification présente certaines limites. Si vous ne cochez que X et Y, les angles calculés varient en fonction de l'angle entre le sujet et l'appareil photo. Vous obtiendrez de meilleurs résultats avec une image de face et de niveau. Vous pouvez également essayez d'étendre cet algorithme Coordonnée Z et voyez s'il fonctionne mieux pour votre cas d'utilisation.

Calculer des angles de points de repère sur Android

La méthode suivante calcule l'angle entre de points de repère. Cela garantit que l'angle renvoyé est compris entre 0 et 180 degrés.

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;
}

Voici comment calculer l'angle de la hanche droite:

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));

Calculer des angles de points de repère sur iOS

La méthode suivante calcule l'angle entre de points de repère. Cela garantit que l'angle renvoyé est compris entre 0 et 180 degrés.

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;
}

Voici comment calculer l'angle de la hanche droite:

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]];