한국의 개발자들을 위한 Google for Developers 국문 블로그입니다.
Pose Animator - 모션 캡처를 통해 브라우저에서 SVG 캐릭터에 생명력을 불어넣기 위한 오픈소스 도구
2020년 6월 4일 목요일
작성자 :
Shan Huang
(
Google Partner Innovation,
Creative Technologist
)
원문은
여기
서
확인 가능하며 정지용
(Google TensorFlow Ecosystem)님이 번역 리뷰에 참여해주셨습니다.
배경
PoseNet
및 (
Mediapipe
의)
Facemesh
TensorFlow.js 모델은 간단한 웹캠을 통해 브라우저에서 실시간으로 사람을 인식할 수 있게 만들었습니다. 캐릭터 애니메이션의 복잡한 기술을 마스터하려고 발버둥치는 애니메이션 마니아로서, 필자는 몸으로 제어되는 대화식 애니메이션을 위해 이들 모델을 사용하여 실험하면서 희망을 보았고 정말 흥미로웠습니다.
그 결과물이 바로 웹캠에서 얻은 신체 인식 결과로 SVG 캐릭터에 생명력을 불어넣는
오픈소스
웹 애니메이션 도구인
Pose Animator
입니다. 이 블로그 게시물에서는 Pose Animator의 기술적 디자인뿐 아니라, 디자이너가 자신만의 캐릭터를 만들고 애니메이션하는 방법도 다룹니다.
TensorFlow.js와 함께 FaceMesh 및 PoseNet을 사용해 전신 캐릭터 애니메이션 표현
2D 벡터 일러스트레이션을 선택해 PoseNet과 FaceMesh에서 얻은 인식 결과를 기반으로 곡선으로 표현된 일러스트레이션을 실시간으로 업데이트하는 것이 Pose Animator의 대략적인 아이디어입니다. 이를 실현하기 위해, Pose Animator는 컴퓨터 그래픽에서 뼈대 기반 애니메이션의 아이디어를 차용해 벡터 캐릭터에 적용합니다.
뼈대 애니메이션에서는 캐릭터가 다음 두 부분으로 표현됩니다.
캐릭터를 그리는 데 사용되는 표면
표면 애니메이션에 사용되는 상호 연결된 뼈로 구성된 계층적 집합
Pose Animator에서는 입력 SVG 파일에서 표면이 2D 벡터 경로로 정의됩니다. 뼈 구조의 경우, Pose Animator는 PoseNet과 FaceMesh의 주요 지점을 기준으로 미리 정의된 리그(rig, 뼈 계층 구조) 표현을 제공합니다. 입력 SVG 파일을 통하여 캐릭터 일러스트레이션과 뼈 구조의 초기 포즈가 주어집니다. 그 이후의 뼈 위치는 ML 모델에서의 인식 결과에 의해 실시간으로 업데이트됩니다.
PoseNet(파란색)과 FaceMesh(빨간색)로 인식된 주요 지점
설명
을 따라 Pose Animator를 위한 자신만의 SVG 캐릭터를 만들어보세요.
PoseNet 및 FaceMesh 출력으로 제어되는 애니메이션의 베지어 곡선
리깅 흐름 개요
전체 리깅(rigging, 뼈대 바인딩) 처리에는 다음과 같은 단계가 필요합니다.
둘 다 T-pose(초기 포즈)에 있는 벡터 일러스트레이션과 미리 정의된 뼈대에 대한 입력 SVG 파일을 파싱합니다.
벡터 경로에 있는 모든 세그먼트에 대하여 각각의 뼈로 인한 가중치 영향과 변환을 반복하여 계산합니다. 이 때 Linear Blend Skinning(이 글에서 이후 설명함)을 사용합니다.
실시간으로 각각의 입력 프레임에서 FaceMesh 및 PoseNet을 실행하고 결과 주요 지점을 사용하여 뼈 위치를 업데이트합니다.
업데이트된 뼈 위치, 뼈 가중치 및 변환으로부터 벡터 세그먼트의 새 위치를 계산합니다.
유사한 인형술사 기능을 제공하는 다른 도구들이 있지만, 그 대부분은 각 요소의 바운딩 박스를 업데이트할 뿐이고 인식한 주요 지점으로 캐릭터의 실제 형상을 변형하지는 않습니다. 또한 전신 인식과 애니메이션 기능을 제공하는 도구는 거의 없습니다. Pose Animator는 개별 곡선을 변형함으로써 얼굴 및 전신 동작의 미묘한 차이를 포착하는 능력이 뛰어나며, 더욱 표현력이 풍부한 애니메이션을 제공하리라는 기대를 갖게 합니다.
리그 정의
리그 구조는 PoseNet과 FaceMesh의 출력 주요 지점에 따라 디자인됩니다. PoseNet은 전신에 대해 17개의 주요 지점을 반환하는데, 이는 리그에 직접 포함하기에 충분할 정도로 간단한 수준입니다. 하지만 FaceMesh는 486개의 주요 지점을 제공하므로, 필자는 어떤 것을 포함할지 좀 더 조심스럽게 골라야 했습니다. 마침내 FaceMesh 출력에서 73개의 주요 지점을 선택했으며, 아래 그림과 같이 모두 합쳐 90개의 주요 지점과 78개의 뼈로 구성된 전신 리그를 만들었습니다.
90개의 주요 지점과 78개의 뼈로 구성된 전신 리그
모든 입력 SVG 파일에는 기본 위치에 이 뼈대가 포함되어 있어야 합니다. 더 구체적으로, Pose Animator는 각각 나타내는 관절로 명명된 앵커 요소가 포함된 'skeleton'(뼈대)라는 그룹을 찾습니다. 샘플 리그 SVG는
여기
에서 찾을 수 있습니다. 디자이너는 리그를 캐릭터에 가장 잘 삽입하기 위해 디자인 파일에서 관절을 자유롭게 이동할 수 있습니다. 극단적인 케이스(예: 무척 짧은 다리/팔 뼈)는 리깅 알고리즘에서 잘 지원되지 않아 부자연스러운 결과가 생성될 수 있지만, Pose Animator는 SVG 파일에서 기본 위치에 따라 스키닝(skinning)을 계산합니다.
디자인 소프트웨어(Adobe Illustrator)에서 리그가 삽입된 일러스트레이션
벡터 경로를 위한 Linear Blend Skinning
Pose Animator는 뼈대 구조를 사용하여 표면을 변형하기 위한 가장 일반적인 리깅 알고리즘 중 하나인 Linear Blend Skinning(LBS)을 사용하는데, LBS는 각 뼈의 영향을 가중치로 적용하여 각각의 뼈만으로 제어되는 변환을 함께 합쳐서 표면의 정점을 변환합니다. 우리의 사례에서는, 정점이 벡터 경로상의 앵커 지점을 가리키며 뼈는 위의 리그에서 연결된 두 주요 지점으로 정의됩니다(예: 주요 지점 ‘leftWrist’와 ‘leftElbow’이 뼈 ‘leftWrist-leftElbow’를 정의함).
수식으로 표현하자면, 정점 v
i
’의 세계 공간 위치는 다음과 같이 계산됩니다.
여기서
- w
i
는 뼈 i가 정점 i에 미치는 영향이고,
- v
i
는 정점 i의 초기 위치를 설명하며,
- T
j
는 뼈 j의 초기 포즈를 현재 포즈에 맞춰주는 공간 변환을 설명합니다.
뼈의 영향은 자동으로 생성하거나 가중치 페인팅을 통해 수동으로 할당할 수 있습니다. Pose Animator는 현재 자동 가중치 할당만 지원합니다. 정점 i에 미치는 뼈 j의 순수한 영향은 다음과 같이 계산됩니다.
여기서 d는 정점 i에서 뼈 j의 가장 가까운 지점까지의 거리입니다. 마지막으로, 정점에 대한 모든 뼈의 가중치를 정규화하여 그 합이 최대 1이 되도록 합니다.
이제, 직선과
베지어 곡선
으로 구성된 2D 벡터 경로에서 LBS를 적용하려면 내부 핸들과 외부 핸들을 사용한 베지어 곡선 선분에 대한 특수 처리가 필요합니다. 곡선 점, 내부 제어점, 외부 제어점에 대해 별도로 가중치를 계산해야 합니다. 그러면 제어점에 대한 뼈의 영향이 더 정확히 포착되므로 외관상 더 나은 결과가 나옵니다.
한 가지 예외적 사례는 있습니다. 내부 제어점, 곡선 점, 외부 점이 동일 선상에 있을 때는 애니메이션 실행 시 세 점이 동일 선상에 있도록 보장하기 위해 세 점 전부에 대해 곡선 점 가중치를 사용합니다. 이는 곡선의 평활도 유지에 도움이 됩니다.
동일 선상의 곡선 핸들은 동일 선상에 머무르기 위해 같은 가중치를 공유함
모션 안정화
LBS는 이미 애니메이션된 프레임을 제공하지만, FaceMesh 및 PoseNet 출력을 그대로 이용하면 눈에 거슬릴 정도로 잡음이 발생합니다. 잡음을 줄이고 더 부드럽고 매끈한 애니메이션을 얻으려면 예측 결과에서 나온 신뢰도 점수를 사용해 각각의 입력 프레임에 고르지 않게 가중치를 주어 신뢰도가 낮은 프레임의 영향을 줄일 수 있습니다.
이 아이디어에 따라, Pose Animator는 프레임 t에서 관절 i의 평활화(smoothing)된 위치를 다음과 같이 계산합니다.
여기서
프레임 i의 평활화된 신뢰도 점수는 다음과 같이 계산됩니다.
극단적인 경우를 생각해봅시다. 연속되는 두 프레임의 신뢰도 점수가 모두 1일 때, 50%의 속도로 최신 위치를 향하여 움직이므로 응답성이 좋고 적당히 매끈해 보입니다. (응답성을 좀 더 시험해보려면 최신 프레임에 대한 가중치를 변경해 접근 속도를 조정할 수 있습니다.) 최신 프레임의 신뢰도 점수가 0일 때는 그 영향이 완전히 무시되어 낮은 신뢰도 결과로 인한 갑작스러운 변동 발생을 방지합니다.
신뢰도 점수 기반 클리핑
신뢰도 점수로 관절 위치를 보간하는 것 외에, 경로를 렌더링해야 할지 여부를 결정하는 최소 임계값도 도입합니다.
경로의 신뢰도 점수는 세그먼트 점의 신뢰도 점수를 평균한 값으로, 이는 영향을 주는 뼈의 점수에 대한 가중 평균입니다. 전체 경로의 점수가 특정 임계값 미만일 때 특정 프레임에 대한 전체 경로를 숨깁니다.
이는 종종 카메라 뷰를 벗어나는 신체 부분인 저신뢰도 영역에 있는 경로를 숨기는 데 유용합니다. 상체 사진을 생각해봅시다. PoseNet은 신뢰도 점수가 낮겠지만 다리와 엉덩이에 대한 주요 지점 예측을 항상 반환합니다. 이 클램핑 메커니즘을 사용해 하체 부분이 이상하게 왜곡된 경로로 나타나는 대신 적절히 숨겨지도록 할 수 있습니다.
전망
메시할 것이냐 말 것이냐
현재 리깅 알고리즘은 주로 2D 곡선을 중심으로 합니다. 이는 뼈의 길이가 비교적 고정적인 게임 내 애니메이션과는 달리, PoseNet과 FaceMesh에서 생성된 2D 리그는 동작 범위가 크고 뼈 길이가 유동적이기 때문입니다. 필자는 현재 입력 경로에서 삼각 메시를 변형할 때보다 베지어 곡선을 변형할 때 더 매끈한 결과를 얻고 있는데, 이는 베지어 곡선이 입력 선의 곡률/일직선을 더 잘 유지하기 때문입니다.
필자는 메시에 대한 리깅 알고리즘을 꼭 개선하고 싶습니다. 그 밖에도, 구부러진 영역 주변으로 볼륨이 얇아지는 것과 같은 제한 사항이 있는 LBS보다 더 발전된 리깅 알고리즘을 탐구해보고 싶습니다.
새로운 편집 기능
Pose Animator는 벡터 그래픽 편집에 강력한 능력을 발휘하지만 애니메이션/스키닝 요구 사항을 해결하는 데는 적합하지 않은 Illustrator와 같은 디자인 소프트웨어에 일러스트레이션 편집을 맡겨둡니다. 필자는 다음을 비롯한 더 많은 애니메이션 기능을 브라우저 내 UI를 통해 지원하고 싶습니다.
주요 지점에 대한 개별 가중치를 수동으로 조정할 수 있도록 하기 위한 스키닝 가중치 페인팅 도구. 이 도구는 자동 가중치 할당보다 더 정밀한 조정을 가능하게 만들 것입니다.
아티스트가 디자인에 사진/그림을 사용할 수 있도록 입력 SVG 파일에서 래스터 이미지를 지원합니다. 이미지 바운딩 박스를 벡터 경로로 쉽게 표현할 수 있으므로, 현재 리깅 알고리즘을 사용하여 간단하게 변형을 계산할 수 있습니다.
직접 체험해 보세요!
기존 캐릭터로 시험해보거나 자신만의 고유한 SVG 캐릭터에 생명력을 불어넣을 수 있는
라이브 데모
를 사용해보세요.
필자는 이 창의적인 커뮤니티에서 어떤 종류의 대화식 애니메이션을 창작해낼지 볼 수 있으리라는 기대에 정말 마음이 들뜹니다. 데모는 인간 캐릭터이지만 Pose Animator는 어떤 2D 벡터 디자인에서나 작동하므로, 한계를 더 멀리 확장하고 싶은 만큼 마음껏 추상적이고 아방가르드한 창의성을 발휘하실 수 있습니다.
애니메이션 가능한 일러스트레이션을 직접 창작하려면
이 가이드를 확인해보세요
! 소셜 미디어에서 해시태그
#PoseAnimator
로 창작품을 꼭 공유해주세요. 궁금한 점이 있으시면 망설이지 마시고 트위터에서
@yemount
로 메시지를 남겨주세요.
또는 소스 코드를 보고 싶으신 분은
github에서 포크
하실 수 있습니다. 즐겁게 활용해보세요!
Contents
ML/Tensorflow
Android
Flutter
Web/Chrome
Cloud
Google Play
Community
Game
Firebase
검색
Tag
인디게임페스티벌
정책 세미나
창구프로그램
AdMob
AI
Android
Android 12
Android 12L
Android 13
Android 14
Android Assistant
Android Auto
Android Games
Android Jetpack
Android Machine Learning
Android Privacy
Android Studio
Android TV
Android Wear
App Bundle
bootcamp
Business
Chrome
Cloud
Community
compose
Firebase
Flutter
Foldables
Game
gdg
GDSC
google
Google Developer Student Clubs
Google Play
Google Play Games
Interview
Jetpack
Jetpack Compose
kotlin
Large Screens
Library
ma
Material Design
Material You
ML/Tensorflow
mobile games
Now in Android
PC
Play Console
Policy
priva
wa
wear
Wearables
Web
Web/Chrome
Weeklyupdates
WorkManager
Archive
2024
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2023
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2022
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2021
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2020
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2019
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2018
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2017
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2016
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2015
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2014
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2013
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2012
12월
11월
10월
9월
8월
7월
6월
5월
3월
2월
1월
2011
12월
11월
Feed