1. 관절 추출
mediapipe pose landmark model을 이용하여 사람의 33개 관절 point 중 원하는 16개의 관절 데이터를 사용
2. 좌/우타 판별
엉덩이와 손의 x좌표를 기준으로 좌타와 우타를 판별 좌타일 경우 이미지를 flip하여 사용하고
마지막에 x좌표를 다시 1-x로 json에 저장하여 우타기준으로 설계한 기능들을 모두 동일하게 수행하며
json에는 좌타 원본 영상기준으로 데이터가 저장됨
3. 척추각 추출
골프에서 척추각을 spine angle이라고 부르며 중요한 요소이다.
따라서 16개의 관절데이터중 어깨 12-11번 관절과 엉덩이 23-24번 관절을 통해 척추를 추정하여 x축과의 각도를 구함
arctan을 통해 각도를 구한다. tan( θ) = y'/x', arctan(tan( θ) = θ
단, mediapipe에서 추출한 y'은 이미지상 위쪽이 0, 아래쪽이 1이기에 1-y'으로 arctan의 input으로 넘겨준다
이로 y의 범위 0~1을 1~0으로 변환한다
ex) arctan(x,-y)
각 7step에서 step별 척추각을 확인하고 척추가 얼마나 들렸는가를 보는데 유용
4. 7step 탐지
모든 frame에 있어서 관절 데이터들을 활용하여 7step의 frame을 추출한다
5. 템포 측정
4번 기능을 통해 추출된 step frame을 통해 각 스텝의 구간별 frame수가 가장 작은 구간을 1로 두고 frame간 비율을 표현
backswing은 address~top, downswing은 top~impact로 step 구간 6가지 + 2가지 총 8가지의 템포를 측정한다
6. Rotation 계산
이미지를 2d로 보지만 real world에서는 3d로써 회전을 한다. 그래서 horizontal, vertical로 나누어 수평,수직에 대한 회전을 구하여 2d image에서 3d 회전을 구한다.
6-1 vertical rotation
어깨를 기준으로 설명하면,
vertical rotation에서는 위아래에 대한 회전각을 구한다. 이또한 arctan을 이용하여 구했다.
여기서 문제가 있었는데 이또한 mediapipe에서 추출한 y data를 1-y로 사용함으로써 해결됐다.
이 사진에서 현재 어깨의 벡터를 생각해보면
다음과 같은 모양의 우상향 벡터이다. 하지만 mediapipe에서 추출한 y의 범위 문제때문에 변환해야된다.
변환을 하지않는다면 얻고자하는 빨간선과 x축의 각이 아닌 검정선과 x축의 각을 구하는 것이다.
따라서 기존에 arctan에 넣는 y좌표는 왼쪽어깨 (x_1, y_1) 오른쪽어깨 (x_2, y_2)일 때,
arctan(y_1 - y_2, x_1 - x_2)의 형태에서 변환하여
왼쪽어깨 (x_1, 1-y_1), 오른쪽어깨 (x_2, 1-y_2) -> arctan(1-y_1 - (1-y_2), x_1 - x_2_ = arctan(y_2-y_1, x_1, x_2)가 된다.
빨간선이 변환전, 파란선이 변환후의 address 어깨각이다.
기존 address자세에서 -5도로 나오는 문제가 5도로 변경되었으며, 올바르게 측정된다.
결과
구간별 angle의 차이를 구했으며, 음수값이 나오면 왼쪽어깨를 기준으로 잡고 오른쪽 어깨를 시계방향으로 돌린것이고,?
양수값이 나오면 왼쪽어깨를 기준으로 잡고 오른쪽어깨를 반시꼐방향으로 돌린것이다.
6-2 horizontal rotation
우리는 영상에서 z축 (depth)를 알지 못한다. 따라서 이론적으로 depth를 어깨기준으로 생각했을 때,
구의 형태를 벗어나지 않는다고 생각했고, 따라서 전체 frame중 어깨선이 가장 길때의 길이가 depth의 최대길이라고 생각했다.
이를 활용하여 모든 frame중 어깨선의 최대 길이를 구하고 가상의 원을 그렸을 때, θ를 구하고 2θ를 반환하였다.
r : 전체 frame 어깨 길이 중 최대 길이 / 2
점 a : 현재 frame의 어깨 좌표
점 b : 다음 frame의 어깨 좌표
직선AB = l이라고 가정
점 c : 원의 중심으로 부터 직선 AB 수선의 발
직선 BC : l/2
여기서 θ를 구해보면 sin(θ) = (l/2)/r, arcsin(sin(θ)) = arcsin((l/2)/r)= θ, 2 θ = arcsin((l/2)/r) * 2가 된다.
이로써 현재에서 다음 frame으로 갈 때 회전각을 알 수 있으며 이를 중첩하여 처음기준으로 얼마나 회전했는지를 알 수 있다.
7-1 path angle 계산 (손목)
7step 기반 구간 별로 오른 손목의 path의 기울기들의 평균을 구하여 x축과의 각도를 계산
해당 구간에서 손목의 움직임의 각도를 알 수 있다.
결과
7-2 path 계산 (귀)
address 기준 귀의 위치와 구간 내의 귀의 위치의 차이를 구해서
얼마나 얼굴이 들리거나 낮춰졌거나 등등 얼굴의 움직임을 알 수 있다.
구간별 최대, 최소 귀의 위치 차이와 평균 귀의 위치차이를 계산
8. back swing / down swing 궤적
down swing과 back swing의 기울기를 비교하여 위치를 구분 (어느 스윙이 앞에 있나)
이때, 두 swing의 frame수가 맞지 않을 경우 interpolation을 수행
9. interpolation
구간 사이에 두 영상의 frame 갯수가 일치하지 않을 가능성이 높으므로 interpolation을 통해 일치시켜서 매칭,
8번기능과 10번기능에 사용
10. cosine similarlity
내적을 통해 cos(θ)를 구한다. A dot B = cos(θ) * llAll * llBll
ex) half ~ impact right wrist
관절에 대한 path는 x,y 2차원 벡터이며 하나의 벡터가 아닌 여러 벡터들로 이루어져있다(frame수-1)
또한 두 영상의 구간 frame수는 다를 수 있다. -> 해결 방법 interpolation
결과
'Project > golf_AI_Serivce' 카테고리의 다른 글
[golf_AI_Service] 1차 마무리 성능 평가 (0) | 2024.08.05 |
---|---|
[golf_AI_Service] 1차 마무리 (0) | 2024.04.01 |
[golf_AI_Service][lambda] 조금 더 자세한 내용 (0) | 2023.08.10 |
[golf_AI_Service][lambda] 전체적인 흐름 (0) | 2023.08.07 |
[golf_AI_Service] Architecture, FlowChart (0) | 2023.08.07 |