Super Kawaii Cute Cat Kaoani DeepMotion: Animate 3D (3) - blender에서 facial motion data 활용하기

연구/DeepMotion

DeepMotion: Animate 3D (3) - blender에서 facial motion data 활용하기

치킨고양이짱아 2023. 6. 7. 17:12
728x90
728x90

https://chickencat-jjanga.tistory.com/69

 

DeepMotion: Animate 3D (1) - Face Tracking 관련조사

full-body motion + facial motion이 모두 포함되어있는 데이터가 필요해서, 비디오로부터 이 데이터들을 뽑아낼 수 있는 방법이 있는지 조사해보다가 DeepMotion에서 관련기술을 지원하고 있다는 사실을

chickencat-jjanga.tistory.com

https://chickencat-jjanga.tistory.com/70

 

DeepMotion: Animate 3D (2) - Motion Tracking 관련조사

https://chickencat-jjanga.tistory.com/69 DeepMotion: Animate 3D (1) - Face Tracking 관련조사full-body motion + facial motion이 모두 포함되어있는 데이터가 필요해서, 비디오로부터 이 데이터들을 뽑아낼 수 있는 방법이

chickencat-jjanga.tistory.com

 
지난 두 포스트에서 Aniamte 3D를 활용하면 full body motion + facial motion data가 담겨있는 fbx 파일을 얻을 수 있다는 사실을 알 수 있었다. 이번 포스트에서는 이 fbx 파일을 blender에 import하여 facial motion data를 어떻게 활용할 수 있을지 알아보고자 한다.

1. fbx 파일을 blender에 import

좌측 상단의 file > import > fbx를 통해 fbx 파일을 blender에 Import 할 수 있다.
import 하게 되면 다음과 같은 화면이 나타나게 된다.

저 armature 왜 mesh를 벗어나서 삐쭉삐쭉 튀어나간 모양으로 되어있는지 모르겠다..어쨌든 mesh만 살펴보면 DeepMotion preview에서 봤던 모양 그대로 잘 재생이 된다.

2. 현재 상태의 facial motion data로의 접근

나는 결국 코드로 blender를 다루어야하므로 코드 상에서 facial motion data로 어떻게 접근하는지 알아보았다.
fbx 파일을 import하면 데이터 구조는 다음과 같이 이루어진다.

이 중에서 표정 데이터가 담겨있는 부분은 face의 하위에 있는 "Mesh.001"이다.
그리고 "Mesh.001"은 코드상에서 다음과 같이 접근할 수 있다.

bpy.data.meshes["Mesh.001"]

그런데 분명히 DeepMotion에서는 facial motion data를 36개의 blendshape로 다룬다고 했었다. (각각의 blendshape는 0.0-~1.0의 부동소수점 값을 가지며 값에 따라 각 blendshape가 담당하는 facial motion이 달라진다.)
각각의 blendshape에 접근할 수 있어야 facial motion data도 얻을 수 있을 것 같은데...각각의 blendshape에는 어떻게 접근할 수 있을까?

위의 사진과 같이 접근할 수 있다. 즉,

bpy.data.meshes["Mesh.001"].shape_keys.key_blocks[원하는 blendshape 이름]

와 같이 각각의 blendshape에 접근할 수 있다.
그리고 각 blendshape는 0.0~1.0의 값을 가진다고 했는데 그 값은 다음과 같이 접근할 수 있다.

bpy.data.meshes["Mesh.001"].shape_keys.key_blocks[원하는 blendshape 이름].value

blendshape의 value에 따른 표정변화가 궁금해져서 아래와 같은 코드를 통해 모든 blendshape의 value를 다 0.0으로 세팅해보았다.

blendshape에서 0.0중립상태를 의미하다보니..굉장히 평온한 표정을 짓는걸 확인할 수 있다.
모두 1.0으로 세팅하게 되면 어떻게 될지도 궁금해져서 아래와 같은 코드를 통해 모든 blendshape의 value를 1.0으로 세팅해보았다.

blendshape에서 1.0최대로 표정을 지은걸 의미하다보니.....진짜 상당히 부담스럽다.......
(참고: len(bpy.data.meshes["Mesh.001"].shape_keys.key_blocks)을 했을 때 결과로 53이 나온다. 52 ARKit BlendShape + Basis까지 해서 53의 결과가 나오는 것 같다. 39 subset에 포함되지 않는 Blendshape의 값을 변경하더라도 표정의 변화가 생긴다.)

3. animation 전체의 facial motion data로의 접근

방금 앞서 설명한 방법은 현재 상태의 facial motion data로 접근하는 방법이였다. 현재 표정을 바꾸거나 현재 표정 data를 얻고 싶을 때는 위와 같이 하면 되지만, 내가 import한 fbx 애니메이션의 표정 data를 읽어오고 싶을 때는 위의 방법이 적절하지 않다. (frame을 일일히 바꾸고 표정 data를 읽어오는건 비효율적이니까..)
그래서 animation 전체의 facial motion data로 접근하고 싶을 때 접근하는 방법을 설명하려고 한다.

일단 facial motion animation 정보는 위의 구조에서 face > mesh.001 > key에 담겨있다.
그리고 우리가 필요한 그 0.0~1.0 사이에 속하는 값에 접근하기 위해서는..조금 많이 파고들어가야한다.

각 blendshape의 value에는 위와 같이 접근할 수 있다. 코드가 의미하는 바를 이해하기 조금 어려울 수 있는데 정리해보자면 각 fcurve에는 한 blendshape의 motion data들이 담겨있게 되고 한 keyframe_points에는 motion data중 한 frame의 motion data가 담기게 된다. 즉..

bpy.data.shape_keys["Key"].animation_data.action.fcurves[내가 원하는 blendshape index].keyframe_points[내가 원하는 frame index].co

와 같이 접근하면 내가 원하는 데이터를 얻을 수 있다.
위의 코드는 Vector 하나를 return 하는데 1) index 0의 값은 몇번째 frame인지를 의미하고(이건 1부터 시작한다) 2) index 1의 값은 이때까지 다루어왔던 0.0~1.0 사이의 값을 가지는 blendshape value라고 보면 된다. 
(참고: 근데 index 0의 값이 정확하게 세팅되어있는거같지 않다...버근가)
(참고: len(bpy.data.shape_keys["Key"].animation_data.action.fcurves)를 했을 때는 39가 나온다!!!!! fcuves에는 DeepMotion이 말했던 것처럼 52 ARKit Blendshape standard의 subset인 39 blendshape에 대한 정보만 담기나보다.)
(참고: bvh를 import 했을 때 fullbody motion의 fcurves[~~].keyframe_points[~~]는 rest pose에 대해 표현되었었다. 그래서 여기서도 data가 rest pose에 대해 표현되나 궁금했는데 그냥 0.0 기준으로 잘 표현된다. rest pose 이런걸 신경쓰지 않고 편하게 사용하면 될 것 같다.)

이렇게 DeepMotion의 Animate 3D의 활용으로 얻어낸 fbx 파일을 blender에 import 했을 때 facial motion data를 어떻게 활용할 수 있는지 알아보았다. 확실히 fullbody motion data보다 facial motion data가 구조도 간단하고 사용하기가 쉬운 것 같다ㅎㅎㅎ
도움이 되었으면!

728x90
728x90