Opções de classificação de poses

Com a API Pose Detection do Kit de ML, é possível derivar interpretações significativas de uma pose verificando as posições relativas de várias partes do corpo. Esta página demonstra alguns exemplos.

Classificação de poses e contagem de repetições com o algoritmo k-NN

Uma das aplicações mais comuns da detecção de poses é o monitoramento de condicionamento físico. Criar um classificador de poses que reconheça poses e contagens de condicionamento físico específicas repetições pode ser um feito desafiador para os desenvolvedores.

Nesta seção, vamos descrever como criamos uma pose personalizada usando o MediaPipe Colab; demonstrar um classificador em funcionamento no app de exemplo do Kit de ML.

Se você não conhece o Google Colaboratory, confira o guia de introdução.

Para reconhecer poses, usamos o algoritmo de k-vizinhos mais próximos (k-NN) porque é simples e fácil de começar. O algoritmo determina a classe do objeto com base na das amostras mais próximas no conjunto de treinamento.

Siga estas etapas para criar e treinar o reconhecedor:

1. Coletar amostras de imagens

Coletamos amostras de imagens dos exercícios direcionados de várias fontes. Qa e escolheu algumas centenas de imagens para cada exercício, como “para cima” e "down" posições para flexões. É importante coletar amostras que cubram diferentes câmeras ângulos, condições do ambiente, formas corporais e variações de exercícios.

Figura 1. Posições de flexão para cima e para baixo

2. Executar a detecção de pose nas imagens de amostra

Isso produz um conjunto de pontos de referência de postura a serem usados no treinamento. Não estamos na detecção de poses, já que vamos treinar nossos próprio modelo na próxima etapa.

O algoritmo k-NN que escolhemos para a classificação de poses personalizada requer uma representação de vetor de atributos para cada amostra e uma métrica a calcular a distância entre dois vetores para encontrar o alvo mais próximo da amostra da pose. Isso significa que devemos converter os pontos de referência de pose que acabamos de obter.

Para converter pontos de referência de poses em um vetor de atributo, usamos as distâncias entre pares entre listas predefinidas de articulações de postura, como a distância entre o pulso e ombro, tornozelo e quadril e pulsos esquerdo e direito. Como a escala das imagens pode variar, normalizamos as poses para que tenham o mesmo tamanho de tronco e tronco vertical orientação antes de converter os pontos de referência.

3. Treinar o modelo e contar repetições

Usamos o MediaPipe Colab para acessar o código do classificador e treinar o modelo.

Para contar repetições, usamos outro algoritmo do Colab para monitorar a probabilidade o limite da posição de uma pose. Exemplo:

  • Quando a probabilidade de "down" de pose passa por um determinado limite para pela primeira vez, o algoritmo marca que a parte classe de poses é inserida.
  • Quando a probabilidade fica abaixo do limite, o algoritmo marca que a "baixo" classe de pose foi encerrada e aumenta o contador.
Figura 2. Exemplo de contagem de repetições

4. Integrar com o app de início rápido do Kit de ML

O Colab acima produz um arquivo CSV que pode ser preenchido com todas as posições de amostra. Nesta seção, você aprenderá a integrar seu arquivo CSV com o App de início rápido do kit de ML para Android para conferir a classificação de poses personalizada em tempo real.

Tente a classificação de poses com amostras agrupadas no app de início rápido

  • Acesse o projeto do app de início rápido do Android no kit de ML do GitHub e verificar se ele foi criado e executado corretamente.
  • Acesse LivePreviewActivity e ative a detecção de posições Run classification em "Configurações" página. Agora você deve ser capaz de classificar flexões e agachamentos.

Adicionar seu próprio CSV

  • Adicione o arquivo CSV à pasta de recursos do app.
  • Em PoseClassifierProcessor, atualize as variáveis POSE_SAMPLES_FILE e POSE_CLASSES para corresponder CSV e amostras de poses.
  • Compile e execute o aplicativo.

A classificação pode não funcionar bem se não houver amostras suficientes. Geralmente, você precisa de cerca de 100 amostras por classe de pose.

Para saber mais e testar por conta própria, confira o MediaPipe Colab e Guia de classificação do MediaPipe.

Como reconhecer gestos simples calculando a distância do ponto de referência

Quando dois ou mais pontos de referência estão próximos, eles podem ser usados para e reconhecer gestos. Por exemplo, quando o ponto de referência de um ou mais dedos em uma a mão está perto do ponto de referência do nariz, de modo que é possível inferir que o usuário é mais provavelmente está tocando o rosto.

Figura 3. Interpretar uma pose

Reconhecer uma postura de ioga com heurística de ângulos

Você pode identificar uma postura de ioga calculando os ângulos de várias articulações. Para exemplo, a Figura 2 abaixo mostra a postura de ioga do Guerreiro II. Os ângulos aproximados que identificam esta posição estão escritas em:

Figura 4. Dividir uma pose em ângulos

Esta posição pode ser descrita como a seguinte combinação de movimentos aproximados ângulos parciais:

  • Ângulo de 90 graus nos dois ombros
  • 180 graus nos dois cotovelos
  • Ângulo de 90 graus na perna da frente e na cintura
  • Ângulo de 180 graus na parte de trás do joelho
  • Ângulo de 135 graus na cintura

Use os pontos de referência de pose para calcular esses ângulos. Por exemplo, o ângulo na perna dianteira direita e na cintura é o ângulo entre a linha a partir da direita ombro para o quadril direito e a linha que vai do quadril direito até o joelho direito.

Depois de calcular todos os ângulos necessários para identificar a pose, você pode conferir para ver se há uma correspondência. Nesse caso, você reconheceu a pose.

O snippet de código abaixo demonstra como usar as coordenadas X e Y para para calcular o ângulo entre duas partes do corpo. Essa abordagem à classificação tem algumas limitações. Verificando apenas X e Y, os ângulos calculados variam de acordo com o ângulo entre o objeto e a câmera. Você receberá o melhores resultados com uma imagem nivelada, direta e de frente. Você também pode tente ampliar esse algoritmo usando a Coordenada Z e conferir se o desempenho é melhor para seu caso de uso.

Como calcular ângulos de pontos de referência no Android

O método a seguir calcula o ângulo entre três pontos de referência. Ele garante que o ângulo retornado esteja entre 0 e 180 graus.

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

Confira como calcular o ângulo no quadril direito:

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

Como calcular ângulos de pontos de referência no iOS

O método a seguir calcula o ângulo entre três pontos de referência. Ele garante que o ângulo retornado esteja entre 0 e 180 graus.

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

Confira como calcular o ângulo no quadril direito:

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