olrlobt
[Pose Estimation] Mediapipe Pose 분석 결과 3D grid로 렌더링하기 본문
토이 프로젝트 진행 중, 3D 결과 값을 보여준다면 사용자에게 더 좋은 결과를 보여 줄 수 있다고 생각하여, 3D Utils의 Grid를 이용하여 사용자에게 결과를 보여주기로 하였다.
Mediapipe
Media pipe는 Google에서 제작한 Machine Lunning Solution으로 얼굴추적, 손추적, 객체 인식과 같은 다양한 기능들을 제공한다.
자세한 내용은 이 전 포스팅에서 다루었다.
https://olrlobt.tistory.com/50
Control_utils_3d
이 전 포스팅에서 사용했던, camera_utils, drawing_utils과는 별도의 util 라이브러리이다.
control_utils_3d는 미디어 파이프 결과를 3D 모델로 만들어 출력하는 것에 도움을 주는 라이브러리이다. WebGL을 사용하기 때문에 브라우저에서만 동작을 하며, 3D 모델링, 3D 렌더링, 사용자 인터랙션과 같은 기능들을 제공한다.
아쉽지만 현재는 Mediapipe에서 제공된 문서는 없는 것으로 보이며, 찾을 수 있는 문서는 아래에 링크해 둔, 패키지 다운로드 사이트 밖에 없었다.
Control_utils_3d npmjs site link :
https://www.npmjs.com/package/@mediapipe/control_utils_3d
오늘은 이 Control_utils_3d 라이브러리를 이용하여 Mediapipe의 Pose Detection 결과를 3D grid로 출력해 보려고 한다.
3D grid 그리기
Grid에 3D로 분석 결과를 그려주기 위해서는 당연한 이야기지만,
media pipe의 Pose Detection 분석이 선행되어야 한다.
자세한 내용은 앞서 언급한 포스팅을 참고해서 구현하면 된다.
포즈 분석을 하게 되면, 다음과 같은 결과가 분석 결과로 제공된다.
이 전 포스팅에서 Canvas에 이미지를 기준으로 분석한 결과는 poseLandmarks로 출력이 된다고 했다. 만약 poseLandmarks로 3D 렌더링을 수행하게 될 경우에, 사람의 위치가 이미지를 기준으로 좌표가 책정이 되기 때문에 일관된 결과를 얻을 수 없다.
따라서 3D grid를 생성하기 위해서는 poseWorldLandmarks 결과를 이용한다.
poseWorldLandmarks는 3D 공간에서 추출한 랜드마크로, 이미지를 기준으로 하지 않고 감지된 사람의 엉덩이 사이의 가상의 점을 기준으로 좌표값을 반환한다. 따라서 이 결과로 3D 렌더링을 하게 될 경우, 카메라의 위치에 상관없이 일정한 값을 얻게 되는 것이다.
LandmarkGrid 객체 생성
먼저, control_utils_3d를 사용하기 위해 라이브러리를 가져온다.
html에서 다음 cdn 구문을 이용하여 쉽게 control_utils_3d 라이브러리 사용이 가능하다.
html :
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/control_utils_3d/control_utils_3d.js" crossorigin="anonymous"></script>
<div class= "landmark_grid_container"></div>
grid가 생성될 div도 같이 만들어준다.
js :
const landmarkContainer = document.getElementsByClassName('landmark_grid_container')[0];
const grid = new LandmarkGrid(landmarkContainer, gridOption);
const gridOption = {
connectionColor: 0xCCCCCC, // 연결 라인의 색상
definedColors: [ // 각 랜드마크의 색상
{name: 'LEFT', value: 0xFF0000},
{name: 'RIGHT', value: 0x0000FF},
{name: 'LEFTCONNECTIONS', value: 0x75fbfd},
{name: 'RIGHTCONNECTIONS', value: 0x00FFAA}],
range: 1, // 그리드의 범위
fitToGrid: true, // 그리드를 landmarkContainer에 꽉 차게 그릴 지
labelSuffix: 'm', // 그리드 라벨 접미사
landmarkSize: 2, // 랜드마크 크기
numCellsPerAxis: 2, // 각 축을 몇개의 셀로 나눌지
showHidden: false, // 숨겨진 랜드마크 표시 여부
centered: true, // 그리드가 landmarkContainer 중앙에 위치할 지
}
js에서 LanmarkGrid 객체를 생성해 준다. 첫 번째 인자로는 grid가 생성될 컨테이너를, 두 번째 인자로는 렌더링에 필요한 옵션을 전달해 준다.
옵션에 적어놓은 주석을 참고하여 원하는 설정을 해주자.
LandmarkGrid 그리기
pose.onResults(drawSkeleton); // 포즈 분석 콜백함수 drawSkeleton()
function drawSkeleton(results) {
/*
* 이 전에 작성한 poseLandmarks 그린 코드
*/
if (results.poseWorldLandmarks) {
grid.updateLandmarks(results.poseWorldLandmarks, [
{list: leftConnections, color: 'LEFTCONNECTIONS'},
{list: rightConnections, color: 'RIGHTCONNECTIONS'},
{list: centerConnections, color: '0xEEEEEE'}]
, [
{list: leftIndices, color: 'LEFT'},
{list: rightIndices, color: 'RIGHT'}
]);
} else {
grid.updateLandmarks([]);
}
}
이 전 포스팅에서 설정한 콜백함수에 위와 같이 추가를 했다.
poseWorldLandmarks 결과가 있을 때만 실행되게 if문을 설정해 주었고,
LandmarkGrid의 updateLandmarks()를 이용하여 grid를 업데이트해 준다.
이때 인자는 updateLandmarks( 랜드마크, 연결 선 색상, 연결 점 색상 )이고,
연결 선 색상과 연결 점 색상은 배열의 형태로 list 속성과 color 속성을 지정해 주어야 한다.
위 코드에서 color 속성의 "LEFTCONNECTIONS"는 앞서 설정한 gridOption의 definedColor 속성의 name과 매칭된다.
결과
3D 예상 값을 잘 추정하여, Grid에 잘 나타내주고 있다.
왼쪽 아래 작은 일시정지 버튼을 이용하여 회전을 멈출 수 있고, 마우스 드래그로 좌, 우 회전 또한 가능하다.
'Spring > Project' 카테고리의 다른 글
[Pose Estimation] Mediapipe 2배속 분석과 분석 결과 중간 부족한 프레임 채우기 (1) | 2023.04.21 |
---|---|
[Pose Estimation] Mediapipe Pose 3D grid에 새로운 축을 적용하고, 새로운 축으로 좌표 변환하기 (3) | 2023.04.04 |
[Spring boot] FFmpeg로 영상 배속 설정하기 (0) | 2023.03.31 |
[Pose Estimation] YOLOv5, MediaPipe로 Multi Pose 구현 시도해보기 (0) | 2023.03.23 |
[Pose Estimation] MediaPipe Pose / 미디어 파이프로 사람 포즈 감지하기 (0) | 2023.03.15 |