AI Research Topic/Pose Estimation

[Pose Estimation] 자세를 분류하는 방법

꾸준희 2021. 3. 1. 17:36
728x90
반응형

 

아래 글은 Google 에서 나온 모바일용 ML Kit 의 한 부분인 자세 추정(Pose Estimation)을 이용하여 자세를 분류하는 방법에 관한 것이다. 자세를 분류하는 방법은 딥러닝을 이용하여 어떤 자세인지 분류하는 방법(e.g. CNN을 이용한 자세 분류)과 기계학습 알고리즘 중 하나인 SVM(Support Vector Machine)을 이용하여 자세를 분류하는 방법, 그리고 아래 Google에서 제시해 놓은 각도를 이용하여 자세를 분류하는 방법이 있다.

 

사실 필자가 생각하기에 가장 좋은 방법은 CNN을 이용하여 스켈레톤을 분류하거나, SVM으로 분류하는 것이 정확도 측면에서 좋다고 생각한다. 하지만 아래와 같이 간단하게 구현해 볼 수 있는 방법도 존재하기 때문에 이를 다뤄보고자 한다. 구글에서 제공하는 문서를 거의 번역만 하여 정리한 수준이니, 참고하길 바란다. 

 

 

 

 

제스처 인식(Recognizing gestures) 

 

두 개 이상의 랜드마크 좌표가 서로 가까이 있을 때 제스처 인식이 가능

  • e.g. 손가락 키포인트가 코의 키포인트에 가까우면 사용자가 얼굴을 만지고 있는 가능성이 가장 높다고 추론

 

 

 

 

 

 

 

요가 자세 인식(Recognizing a yoga pose)

 

Warrior  II 요가자세

 

다양한 관절 각도를 계산하여 요가 자세를 식별 할 수 있음

 

  • e.g. 위 요가 자세는 대략적인 신체 부위 각도를 다음과 같이 계산 할 수 있음
    • 양쪽 어깨에서 90도 각도를 가짐
    • 양쪽 팔꿈치에서 180도 각도를 가짐
    • 앞 다리와 허리에서 90도 각도를 가짐
    • 뒤 무릎에서 180도 각도를 가짐
    • 허리에서 135도 각도를 가짐

 

포즈 키포인트를 통해 다음과 같이 각도를 계산 할 수 있음

  • e.g. 오른쪽 앞다리와 허리의 각도는 오른쪽 어깨에서 오른쪽 엉덩이까지의 선과 오른쪽 엉덩이에서 오른쪽 무릎까지의 선 사이의 각도

 

포즈를 식별하는데 필요한 모든 각도를 계산했다면 일치하는 항목이 있는지 확인 가능하며, 아래와 같은 주의 사항이 있음 

 

 

주의 사항

  • x 및 y 만 확인하면 객체와 카메라 사이의 각도에 따라 계산된 각도가 달라짐
  • 최대한 평평하고 직관적인 정면 이미지여야 최상의 결과를 얻을 수 있음
  • z 좌표를 사용하여 알고리즘을 확장할 수 있음

 

 

 

 

 

 

x, y 좌표를 사용하여 두 신체 부위 사이의 각도를 계산 하는 방법은 다음과 같음

 

1. 안드로이드(Android)에서의 랜드 마크 각도 계산 (JAVA)

 

1.1 3개의 랜드마크 사이의 각도를 계산하는 방법 (반환되는 각도가 0도에서 180도 사이인지 확인) 

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

 

1.2 오른쪽 엉덩이의 각도를 계산하는 방법

double rightHipAngle = getAngle(
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER),
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP),
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE));

 

 

 

2. IOS에서 랜드마크 각도 계산 (Swift)

 

2.1 3개의 랜드마크 사이의 각도를 계산하는 방법 (반환되는 각도가 0도에서 180도 사이인지 확인) 

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
  }

 

2.2 오른쪽 엉덩이의 각도를 계산하는 방법

let rightHipAngle = angle(
      firstLandmark: pose.landmark(ofType: .rightShoulder),
      midLandmark: pose.landmark(ofType: .rightHip),
      lastLandmark: pose.landmark(ofType: .rightKnee))

 

 

 

 

참고자료 : developers.google.com/ml-kit/vision/pose-detection/classifying-poses#java

 

Pose Classification Tips  |  ML Kit  |  Google Developers

With the ML Kit Pose Detection API, you can derive meaningful interpretations of a pose by checking the relative positions of various body parts. This page demonstrates two examples. Recognizing gestures When two or more landmarks are close to each other,

developers.google.com

 

728x90
반응형