# 3D Vision 期未報告-Expressive Body Capture: 3D Hands, Face, and Body from a Single Image
## 組員資料
姓名:邱繼群、李承澤
學號:M113010023、M113010017
## 報告論文
這次要報告的論文為 [Expressive Body Capture: 3D Hands, Face, and Body from a Single Image](https://openaccess.thecvf.com/content_CVPR_2019/papers/Pavlakos_Expressive_Body_Capture_3D_Hands_Face_and_Body_From_a_CVPR_2019_paper.pdf) ,這是一篇來自於 CVPR 2019 的論文,在這篇論文中提出 __SMPL-X 3D模型[1]__ 與 __SMPLIfy-X[1]__ 演算法,實現從單一 RGB 影像同時捕捉身體、手和臉部表情,進一步生成對應的 __3D 模型__ ,藉由這個 3D 模型能夠更加精確的描述 2D 影像中人物的姿態、手和臉部表情。
## 相關知識說明
在查閱這次的論文發現,發現整份論文並沒有詳細說明相關的知識點,所以當初在閱讀文獻時相當吃力,後來查閱相關的文獻,才對於整個論文的描述有更深入的了解。
### 人體動作捕捉
在建立 3D 動畫時,為了能使得角色的動作更加自然,常會使用到動作捕捉(Motion Capture)的技術來記錄與分析人類或動物的運動軌跡、速度或加速度。目前通常會利用 __光學跟蹤器、功能穿戴裝置或情境感應器__ 等等裝置,來捕捉人體的動作藉此讓製作出的動畫可以做出類似的動作。
當然前面提到的 __光學跟蹤器、功能穿戴裝置或情境感應器__ 的設備成本都是相當的高,也因此如果能夠從單張的 2D 影像來進行人體動作捕捉,在達到同樣目的的同,還能能夠大幅的降低成本。
### 3D 人物建模
#### 人體關節樹

*人體關節樹 (圖片取自 [三维人体动捕模型 SMPL| 四一的随写 ](https://yunyang1994.github.io/2021/08/21/%E4%B8%89%E7%BB%B4%E4%BA%BA%E4%BD%93%E6%A8%A1%E5%9E%8B-SMPL-A-Skinned-Multi-Person-Linear-Model/))*
動畫師在進行3D人物建模時,會將動畫人物呈現 T-pose (在 SMPL 中稱為zero-pose) 擺放,並定義一套 __人體關節樹__ ,如上圖所示。在這個關節樹中,每一個 __關節__ 都會對應對一個 __父節點__,父節點與子節點相聯會形成一個 __關節__,而關節樹的設計將會直接影響動畫人物的運動。其中每一個關節都有自己的座標系,人體在運動時都是相對其父節點發生旋轉,如下圖所示[11]。

*每一個關節點上的座標 (圖片取自 [三维人体动捕模型 SMPL| 四一的随写 ](https://yunyang1994.github.io/2021/08/21/%E4%B8%89%E7%BB%B4%E4%BA%BA%E4%BD%93%E6%A8%A1%E5%9E%8B-SMPL-A-Skinned-Multi-Person-Linear-Model/))*
#### Blend Skinning
在進行 3D 模型的建製,如果僅僅知道人體的關節樹還不夠,因此我們還需要一個方法能夠將關節與骨架進行包覆,而 Blend Skinning 是利用皮膚或是表面的表示法(像是triangle mesh),來包覆底層的骨架,透過這樣的方法可以用來傳答在這個骨架下人物的外觀,並且當底層的骨架改變時人物的外觀也會跟著變形[7],其中mesh表面上的每一個vertex都是由其鄰近骨骼利用加權值進行轉換的。

*(圖片取自 [Lecture-9-Skinning and Body Representations.pdf](https://www.cs.cmu.edu/~yaser/Lecture-9-Skinning%20and%20Body%20Representations.pdf))*
### 2D Motion Capture
正因為關節樹是如此的重要,也因此許多研究進行2D的人體姿態估計,會找出影像中人物的關節點與這些關節點是如何相聯的,如下圖中左二與左三。在進行2D的姿態估計的任務中,會利用一台或是多台相機,不過缺點是只能捕捉到2D的運動訊息,也因此精確度相當的低,對於了解整個人物的姿態相當不足,只能大致了解人物的關節點的位置,對於人物的外表與實際的人體姿態不能清礎的描述。也因此如果能將 2D 影像進一步地建立對應的 3D 模型,如下圖中右一與右二的圖形,比起僅知道人體的關節點,這種 3D 模型更能清礎的描述人體的實際姿態。

*(圖片取自 [Expressive Body Capture: 3D Hands, Face, and Body from a Single Image](https://openaccess.thecvf.com/content_CVPR_2019/papers/Pavlakos_Expressive_Body_Capture_3D_Hands_Face_and_Body_From_a_CVPR_2019_paper.pdf))*
然而在進行三維重建的方法中,我們能想到最簡單的方法就是透過 2D 影像中得到的關節點來進行三維模型的重建,但是僅利用 2D 關節點來進行轉換,所得到的訊息是不足夠的,因為同一種 2D 關節點在進行 3D 的轉換時,可以得到多種的映射的可能性,因此僅單純利用 2D 關節進行姿態估計是有問題,除非我們利用 __多視角__ 得到的影像才能解決這項問題[13]。
因此如果我們想利用單一視角來得到另一種可行的方案就是利用 __人體姿態先驗__,也就是先找出人體能夠透過實際的人體排除那些人體不可能做得到的極限動作,或是利用大型的 3D 人體姿態的資料集,透過機器學習的方法來學習人體正常的姿態,再從 2D 的影像中,擬合出可能的 3D 的人體模型。而本篇論文所使用到的演算法 __SMPLify-X__,即是透過這種這種經過大型資料集訓練得到的 3D 人體模型 __SMPL-X__,再進一步從 2D 影像擬合出對應的 3D 人體模型。
### SMPL、SMPL-X、SMPLify 與 SMPLify-X 之間的關係
由於本篇論文的演算法 SMPLify-X 提到 SMPL、SMPL-X 與 SMPLify,這些名稱相似的演算法,以下簡單說明這些演算法彼此之間的關係。
#### SMPL
SMPL[2] 是由數千張的人物掃描所訓練出來的人體 3D 模型,SMPL在人體的 __動作__ 與 __形狀__ 上,有著比其他方法像是LBS與DQBS更加真實的結果。
#### SMPL-X
SMPL在人物的細節處並沒有過多的捉摸,為此 SMPL-X[1] 在SMPL的基礎上做了改良,添加更多的形狀和姿態變化,使得頭部、手部首與手指可以更加精細,也因此建立出來的 3D 模型能夠呈現人體更多細節。
#### SMPLify
在進行人體動作捕捉時,如果要將2D的影像進行3D的重建,由於2D關節點在進行3D的轉換時,可以得到多種的映射進而產生 __ambiguous__ ,也因此難以的得到良好的結果。
SMPLify[3] 是一個將 2D 影像影進行 3D 重建的演算法之一,將 SMPL 作為人體形狀和姿態的先驗知識,3D 人體姿態擬合到二維影像中的 Key Point,並且這些 2D 的 __關鍵點__ 是由 DeepCut 網路所得到。除此之外,更由於使用了 SMPL 作為人體形狀和姿態的先驗知識,使得在三維重建的過程中可以避免產生 __ambiguous__ 。
#### SMPLify-X
過去SMPLify結合了SMPL的模型,能夠順利的將輸入的 2D 影像建立對應的 3D 模型,但是受限於 SMPL 模型僅能建立人體大致的姿態動作,不能更加細膩地描述人的的手部姿態與臉部表情。前面一段提到的 SMPLify 是在 SMPL 的基礎上進行 2D 影像的 3D 模型建製,而 SMPLify-X 是在 SMPLify 的基礎上進行開發,利用 SMPL-X 作為人體形狀和姿態的先驗知識,將輸入的 2D 影像建製出對應的 3D 模型,使得建構出來的 3D 模型能夠捕捉更多人體的細節,像是臉部表情與手部動作。
## SMPL
為了能夠更清礎地描述 SMPLify-X 演算法,查閱 SMPL 的原始文獻[2],以下簡單說明 SMPL 的運作。
### 參數說明
- $N$:一個具有 __6890__ 個 vertices 的 mesh
- $K$:__23__ 個關節
#### 模型輸入參數
- $\vec{\beta}$:形狀參數,是一組具有 $10$ 維度的向量,這組參數主要是用作定義一個人體的高矮胖瘦。
- $\vec{\theta}$:姿態參數,具有 $(K+1)\times 3$ 個參數,這組參數主要是用來定義一個人體的姿體。其中 $K$ 代表人體關節點, $1$ 則代表根節點,如下圖所示;$\vec{\theta}=[\vec{w}_{0}^{T},...,\vec{w}_{k},...,\vec{w}_{K}^{T}]^{T}$ ,$\vec{w}_{k} \in \mathbb{R}^{3}$ 代表人體關節樹中第 k 個關節,相對於其父節點的 axis-angle。

*人體的 $K+1$ 個關節點 (圖片取自 [SMPL: A Skinned Multi-Person Linear Mode](https://dl.acm.org/doi/pdf/10.1145/2816795.2818013))*

*Axis–angle representation (圖片取自 [Axis–angle representation - Wikipedia](https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation))*
#### 模型可學習的參數
- $\mathbf{\bar{T}} \in \mathbb{R}^{3N}$:mean shape of template, 是藉由統計得到的結果,在這個基本姿態下為 __zero pose__ $\theta^{*}$。
- $\mathcal{W} \in \mathbb{R}^{N\times K}$:blend weight的集合,代表vertices對應到關節的參數。
- $\mathcal{P}\in \mathbb{R}^{3N\times 9K}$:Pose blendshpae
- $\mathcal{S}\in \mathbb{R}^{3N\times |\vec{\beta}|}$:Shape blendshpae
#### 模型中的函數
- $B(\vec{\beta})$:$\mathbb{R}^{|\vec{\beta}|}\mapsto \mathbb{R}^{3N}$,為一個與形狀參數有關的blend shape函數,目的是給定一組 $\vec{\beta}$ ,得到每一個vertex相對於 $\mathbf{\bar{T}}$ 的位移向量。簡單來說,這個函數說明了人物形狀所造成的變形。
- $B(\vec{\theta})$:$\mathbb{R}^{|\vec{\theta}|}\mapsto \mathbb{R}^{3N}$,為一個與姿態參數有關的blend shape函數,目的是給定一組 $\vec{\theta}$ ,得到每一個vertex相對於 $\mathbf{\bar{T}}$ 的位移向量。簡單來說,這個函數說明了姿勢所造成的變形。
- $J(\vec{\beta})$:$\mathbb{R}^{|\vec{\beta}|}\mapsto \mathbb{R}^{3K}$,藉由人物的形狀參數 $\beta$ 來預測物人物的關節點位置。
- $W(\cdot)$:代表 blend skinning function,可以是LBS或是DQBS。
- $M(\vec{\beta},\vec{\theta};\Phi)$:$\mathbb{R}^{|\vec{\theta}|\times|\vec{\beta}|}\mapsto \mathbb{R}^{3N}$,代表SMPL整個模型的函數,目的是透過給定 __形狀參數__ $\vec{\beta}$ 與 __姿態參數__ $\vec{\theta}$ 得到所有vertices在空間中的位置。其中 __";"__ 右邊的 $\Phi$ 代表整個SMPL模型的可學習的參數。
### 其他方法所面臨的問題
過去 Blend Skinning 技術,像是 LBS 與 DQBS 會出現皮膚塌陷和皺褶的問題,作者稱之為 __taffy(太妃糖)__ 和 __bowtie(領結)__,如下圖所示,在手肘與大腿上部部的彎曲之處可以看到不自然皺褶。為此 SMPL 作者認為這項問題可以 __透過大數據的方式__ 來藉此學習正常的自然的皺褶。下圖為 SMPL 與 LBS 和 DQBS 的進行 Blend Skinning 的比較,可以發現 SMPL 在一些特定的姿態下,看起來比其他正常許多。

*(圖片取自 [SMPL: A Skinned Multi-Person Linear Mode](https://dl.acm.org/doi/pdf/10.1145/2816795.2818013))*
### 方法
#### Blend Skinning
##### 標準的LBS公式
標準的LBS公式如下:
$$W(\mathbf{\bar{T}},\mathbf{J},\vec{\theta},\mathcal{W}):\mathbb{R}^{3N\times 3K\times|\vec{\theta}|\times|\mathcal{W}|}\mapsto \mathbb{R}^{3N}$$
透過給定的參數 $\mathbf{\bar{T}},\mathbf{J},\vec{\theta},\mathcal{W}$ 來得到所有vertices在空間的位置。其中 $\mathbf{\bar{T}}$ 上的每一個vertex $\mathbf{\bar{t_{i}}}$ ,將會被轉換到 $\mathbf{\bar{t_{i}}}'$,相關的轉換公式如下所示:
$$\mathbf{\bar{t_{i}}}' = \sum_{k=1}^{K}w_{k,j}G'_k(\vec{\theta},\mathbf{J})\mathbf{\bar{t_{i}}}$$
$$G'_k(\vec{\theta},\mathbf{J})=G_k(\vec{\theta},\mathbf{J})G_k(\vec{\theta^{*}},\mathbf{J})^{-1}$$
$$G_k(\vec{\theta},\mathbf{J})=\prod_{j\in A(k)} \begin{bmatrix}
\begin{array}{c|c}
\text{exp}(\vec{w}_j)& \mathbf{j}_j\\
\hline \vec{0}& 1
\end{array}
\end{bmatrix}$$
- $w_{k,j}$:為 $\mathcal{W}$ 中的元素,代表著第 $k$ 個關節影響 vertex $i$ 旋轉的程度。
- $G_k(\vec{\theta},\mathbf{J})$:代表第 $k$ 個關節的變換矩陣,並根據姿態參數 $\vec{\theta}$ 和全局關節位置 $\mathbf{J}$ 進行計算。
- $G_k(\vec{\theta^{*}},\mathbf{J})^{-1}$:可以用來消除初始狀態對結果的影響。
- $G'_k(\vec{\theta},\mathbf{J})$:代表經過消除初始狀態影響的情況下,第 $k$ 個關節的變換矩陣,並根據姿態參數 $\vec{\theta}$ 和全局關節位置 $\mathbf{J}$ 進行計算。這個變換矩陣用於將頂點從初始位置變換到新的位置,以反映第 $k$ 個關節的姿態和位置對頂點位置的影響。
- $\text{exp}(\vec{w}_j)$ 是由 _Rodrigues formula_ 所得到的旋轉矩陣
$$\text{exp}(\vec{w}_j) = I+ \widehat{\bar{w}}_j\text{sin}(\left \| \vec{w}_j \right \|)+\widehat{\bar{w}}_j^2\text{cos}(\left \| \vec{w}_j \right \|)$$
##### SMPL 的 Blend Skinning
SMPL在以上的公式的基礎上做了改良
$$M(\vec{\beta},\vec{\theta};\Phi)=W(T_{P}(\vec{\beta},\vec{\theta}),J(\vec{\beta}),\vec{\theta},\mathcal{W})$$
$$T_{P}(\vec{\beta},\vec{\theta})=\mathbf{\bar{T}}+B_{S}(\vec{\beta})+B_{P}(\vec{\theta})$$
除此之外,$\mathbf{\bar{t}}_{i}$ 的轉換將修改成如下所示,其中$\mathbf{b}_{S,i}(\vec{\beta})$、$\mathbf{b}_{P,i}(\vec{\theta})$ 分別代表 vertex $\mathbf{\bar{t}}_i$ 在 $B_{S}(\vec{\beta})$ 與 $B_{P}(\vec{\theta})$ 中的位移向量。
$$\bar{t_{i}}' = \sum_{k=1}^{K}w_{k,j}G'_k(\vec{\theta},\mathbf{J}(\vec{\beta}))(\mathbf{\bar{t}}_{i}+\mathbf{b}_{S,i}(\vec{\beta})+\mathbf{b}_{P,i}(\vec{\theta}))$$
###### Shape Blend Shapes
不同的人會有不同的形狀參數 $\vec{\beta}$ ,也因此會造就出不同的人體外形,而 $B_{S}(\vec{\beta})$ 的公式如下:
$$B_{S}(\vec{\beta};\mathcal{S})=\sum_{n=1}^{|\vec{\beta}|}\beta_{n}\mathbf{S}_{n}$$
- $|\vec{\beta}|$ :形狀系數的數量
- $\mathbf{S}_{n} \in \mathbb{R}^{3N}$:與不同的形狀系數 $\beta_{n}$相乘,代表對於每一個 veterx 的位移向量。__(需修改)__
- $\mathcal{S}=[\mathbf{S}_{1},...,\mathbf{S}_{n}]\in \mathbb{R}^{3N\times |\vec{\beta}|}$:$\mathcal{S}$ 將會是透過大數據訓練所得到的結果。__(需修改)__
如果我們將 $\mathbf{\bar{T}}+B_{S}(\vec{\beta})$ 可得到以下的結果,可以下圖中發現當 $\vec{\beta}$ 改變,會對應到不同的人物外表。

*(圖片取自 [SMPL 官方網站](https://smpl.is.tue.mpg.de/))*
###### Pose Blend Shapes
由於人體的表面形狀如果只考慮 $\vec{\beta}$ 的話,只能得到一個特定高矮胖瘦的表面,但是實際上不同 $\vec{\theta}$ 的動作下會直接影響人體局部具體的形狀,從下圖中可以清楚的發現,隨著左邊的動作改變,右邊有一些部位也會跟著改變。再舉例另一個例子,當人體站著的姿勢,肚子可能並不會凸出來,但是如果是坐著的姿勢肚子就會凸出來[13]。
$B_{P}(\vec{\theta})$ 的公式如下示:
$$B_{P}(\vec{\theta};\mathcal{P})=\sum_{n=1}^{9K}(R_{n}(\vec{\theta})-R_{n}(\vec{\theta}^{*}))\mathbf{P}_{n}$$
- $R:\mathbb{R}^{|\vec\theta|}\mapsto \mathbb{R}^{9K}$這個函數是將23個關節向量轉成旋轉矩陣$\text{exp}(\vec{\omega})$,並將旋轉矩陣中的9個元素互相串接成一個 $\mathbb{R}^{9K}$ 的矩陣。
- $\mathbf{P}_{n}\in \mathbb{R}^{3N}$:代表基於不同 $R_{n}(\vec{\theta}^{*})$ ,vertex的位移向量。__(需修改)__
- $\mathcal{P}=[\mathbf{P}_{1},...,\mathbf{P}_{9K}]\in \mathbb{R}^{3N\times 9K}$:$\mathcal{S}$ 將會是透過大數據訓練所得到的結果。__(需修改)__
除此之外,這裡減去 $R_{n}(\vec{\theta}^{*})$ 是為了確保在 __zero pose__ 的情況下,$B_{P}(\vec{\theta})$ 的結果為0。
當以下為 $\mathbf{\bar{T}}+B_{S}(\vec{\beta})+B_{P}(\vec{\theta})$ 的結果,我們可以發現當的人物的動作改變,人體的外表也會有所變化。

*(圖片取自 [SMPL 官方網站](https://smpl.is.tue.mpg.de/))*
###### Joint Locations
人體的外形不同,同時關節的位置也會有所不同,經過以上兩種混合成形,作者針對 __zero pose__ 形成的mesh來估計 __zero pose__ 關節的所在位置,這樣才可以確保對這些關節點進行旋轉時,能夠更加精確地得到我們的想要的模型。因此我們希望得到一個變換矩陣 $\mathcal{J}\in \mathbb{R}^{N\times 3}$ 使得在且不同的人物形狀參數 $\beta$ 下可以得到人體關節位置。
$$J(\vec{\beta};\mathcal{J},\mathbf{\bar{T}},\mathcal{S})=\mathcal{J}(\mathbf{\bar{T}}+B_{S}(\vec{\vec{\beta};\mathcal{S}}))$$
除此之外, $\mathcal{J}$ 是一個大數據資料所訓練出來的回歸矩陣。
###### Blend weight
$\mathcal{W} \in \mathbb{R}^{N\times K}$為 blend weight 的集合,代表vertices對應到關節的參數,簡單來說就是關節影響 mesh 上每一個 vertex 的程度。
下圖中的(a)說明每一個關節影響不同vertex的分割區域,圖(b)經過擴散得到初始化的blend weight $\mathcal{W}_{I}$

*(圖片取自 [SMPL: A Skinned Multi-Person Linear Mode](https://dl.acm.org/doi/pdf/10.1145/2816795.2818013))*
###### SMPL model
最後我們可以得到SMPL model如下式所示,其中 $\Phi=\{;\mathbf{\bar{T}},\mathcal{S},\mathcal{P},\mathcal{W}\}$ 為需透過大數資料所學習的參數。
$$M(\vec{\beta},\vec{\theta};\Phi)=W(T_{P}(\vec{\beta},\vec{\theta};\mathbf{\bar{T}},\mathcal{S},\mathcal{P}),J(\vec{\beta};\mathcal{J},\mathbf{\bar{T}},\mathcal{S}),\vec{\theta},\mathcal{W})$$

*(圖片取自 [SMPL: A Skinned Multi-Person Linear Mode](https://dl.acm.org/doi/pdf/10.1145/2816795.2818013))*
## Expressive Body Capture: 3D Hands, Face, and Body from a Single Image
### Introduction
為了能更進一步的分析人體的姿態變化與情緒變化,本篇論文主要是討談如何利用單一視角的 2D 影像,計算出人體身體、手部與臉部的 3D 模型。為了能夠更清礎的表達出人的手部與表情變化,使用 SMPL-X 作為人體姿態的先驗,先利用 OpenPose 來捕捉 2D 影像中人體的 __關鍵點__,再透過 SMPLify-X 來擬合 SMPL-X 模型。除此之外,由於不同性別的 3D 模型在外型上會有些微的差距,因此輸入的影像會先進行性別的分類(女性、男性與中性),來選擇對應的身體模型。
### 結合 SMPL-X 模型
SMPL-X[1] 是 SMPL 的擴展版本,在 SMPL 的基礎上結合 FLAME 臉部模型與 MANO 模型,因此 SMPL-X 所產生的模型能夠更進一步地描繪人體的身部、臉部與手部的部分。此外,因為是 SMPL 的擴展版本,所以許多參數、方法與計算的相關公式大多與SMPL類同。

*(圖片取自 [smplx_poster.pdf (mpg.de)](https://ps.is.mpg.de/uploads_file/attachment/attachment/517/smplx_poster.pdf))*
#### 參數說明
- $N$:一個具有 __10475__ 個 vertices 的 mesh
- $K$:__54__ 個關節,其中包含脖子、顎、眼球與手指
##### 模型輸入參數
- $\vec{\beta}$:形狀參數。
- $\vec{\theta}$:姿態參數又可分為$\theta_{f}, \theta_{h},\theta_{b}$,其中 $\theta_{f}$ 為顎部的關節,$\theta_{h}$ 為手指的關節,$\theta_{b}$ 依舊為身體的關節。
- $\vec{\psi}$:臉部表情參數,這個參數是 SMPl 中沒有。
#### 方法
SMPL-X 模型的公式如下所示
$$M(\vec{\beta},\vec{\theta},\vec{\psi};\Phi)=W(T_{P}(\vec{\beta},\vec{\theta},\vec{\psi};\mathbf{\bar{T}},\mathcal{S},\mathcal{E},\mathcal{P}),J(\vec{\beta};\mathcal{J},\mathbf{\bar{T}},\mathcal{S}),\vec{\theta},\mathcal{W})$$
$$T_{P}(\vec{\beta},\vec{\theta},\vec{\psi};\mathbf{\bar{T}},\mathcal{S},\mathcal{E},\mathcal{P})=\mathbf{\bar{T}}+B_{S}(\vec{\beta};\mathcal{S})+B_{E}(\vec{\psi;\mathcal{E}})+B_{P}(\vec{\theta};\mathcal{P})$$
其中 $B_{S}(\vec{\beta})$ 、 $B_P(\vec{\theta})$ 與 $J$ 所代表的函意與 SMPL 相同,$W(\cdot)$也與SMPL相同代表標準的 LBS
$$B_{S}(\vec{\beta};\mathcal{S})=\sum_{n=1}^{|\vec{\beta}|}\beta_{n}\mathbf{S}_{n}$$
$$B_{P}(\vec{\theta};\mathcal{P})=\sum_{n=1}^{9K}(R_{n}(\vec{\theta})-R_{n}(\vec{\theta}^{*}))\mathbf{P}_{n}$$
$$J(\vec{\beta};\mathcal{J},\mathbf{\bar{T}},\mathcal{S})=\mathcal{J}(\mathbf{\bar{T}}+B_{S}(\vec{\vec{\beta};\mathcal{S}}))$$
至於 $B_{E}(\vec{\psi})$ 代表與臉部表情相關的 Blend shape
$$B_{E}(\vec{\psi};\mathcal{E})=\sum_{n=1}^{|\psi|}\psi_{n}\mathcal{E}$$
#### SMPL-X模型訓練
在開始進行 SMPL-X 的模型訓練前,會先人工建製 3D 模版,並且這個模版的手部和臉部會分別與 MANO 和 FLAME (分別用於建制手部與臉部的模型)中的模版匹配。接著這個 3D 模版會將資料集的 3D 掃描進行 3D 對位得到 4 個訓練資料集,來訓練形狀空間參數 $\{\mathcal{S}\}$ ,人體姿態空間參數 $\{\mathcal{W,P,J}\}$,並由於人體的 3D 掃描會限制手部與臉的解析度,所以利用 MANO 參數來捕捉手部的姿勢,利用 FLAME 的模型來捕捉臉部的模型。
### SMPLify-X:SMPL-X from single image
為了使單張影像能夠匹配 SMPL-X 模型,作者定義了一個 __目標函數__ 如下示,並將其視為一個 __最佳化的問題__。
$$E(\vec{\beta},\vec{\theta},\vec{\psi}) = E_{J}+\lambda_{\theta_{b}}E_{\theta_{b}}+\lambda_{\theta_{f}}E_{\theta_{f}}+\lambda_{m_{h}}E_{m_{h}}+\lambda_{\alpha}E_{\alpha}+\lambda_{\beta}E_{\beta}+\lambda_{\mathcal{E}}E_{\mathcal{E}}+\lambda_{\mathcal{C}}E_{\mathcal{C}}$$

*(圖片取自 [smplx_poster.pdf (mpg.de)](https://ps.is.mpg.de/uploads_file/attachment/attachment/517/smplx_poster.pdf))*
其中 $\theta_{b}$、$\theta_{f}$ 與 $m_{h}$ 分別代表身體、臉部與手部的姿態向量,此外 $\theta_{b}(Z)$ 為一參數方程式,其中 $Z \in \mathbb{R}^{32}$ 為 variational autoencoder(VAE) 的 latent vector,是一個較低維度的潛在變量(更細節的部分會在下一小節進行說明)。此外這個目標函數主要是用於測試與推理階段,並且分成 __圖像匹配項__ 、__先驗項__ 、__正則項__ 。
__正則項__ 則是用來控制結果的平滑度、連續性或其他約束以避免過擬合與不穩定的解,在目標函數中的 $E_{\theta_{f}}(\theta_f)$ 、 $E_{m_{h}}(m_{h})$ 、 $E_{\beta}(\beta)$ 與 $E_{\mathcal{E}}(\psi)$ 為簡單的 $L_2$ 正則項。
$E_{\alpha}(\theta_{b})=\sum_{i\in(elbows,knees)}\text{exp}(\theta_i)$ 是用來懲罰肘部與膝蓋極端彎曲的情況,來限制肘部與膝蓋極端彎曲程度,使得結果能夠更加自然。
$E_{C}$ 為穿透懲罰項,這個項的目的是防止模型中不同部位的幾何體相互穿透,即防止身體的不合理重疊或穿越。這在人體建模中很重要,因為現實世界中的身體部位是彼此分開的,不應該互相穿透。在 SMPLify-X 裡使用 BVH 來處理三維場景中的物體碰撞檢測。
$$E_C(\theta)=\sum_{(f_s(\theta),f_t(\theta))\in C}\{\sum_{v_s \in fs}||-\Psi_{f_t}(v_s)n_s ||^2+\sum_{v_t \in ft}||-\Psi_{f_s}(v_t)n_t ||^2\}
$$

*(圖片取自 [smplx_poster.pdf (mpg.de)](https://ps.is.mpg.de/uploads_file/attachment/attachment/517/smplx_poster.pdf))*
而目標函數的 __先驗項__ $E(\theta_{b})$ 是利用 VAE 所學習的潛在變量來對姿態和形姿進行約束。
最後 __圖像匹配項__ $E_{J}(\beta,\theta,K,J_{set})$ 是用於評估預測姿態和形狀與圖像之間的差異,$E_{J}(\beta,\theta,K,J_{set})$ 的公式如下所示,主要是利用重投影的方式,來最小化 2D 影像的關節點 $J_{est}$ 與 SMPL-X 中每一個 3D 關節點 $R_{\theta}(J(\beta))_{i}$ 的 2D 投影之間的差距,其中 $\Pi_{K}$ 代表利用相機參數 $K$ 進行 3D 到 2D 的投影,2D 影像的關節點是由 OpenPose 預測得到。考慮到偵測中的雜訊問題,$\omega_{i}$ 表示為每一個關節的貢獻會根據偵測的可信度分數進行加權,$\gamma_{i}$ 則代表對每一個關節的權重進行優化,最後 $\rho$ 代表著 _Geman-McClure_ 誤差函數。
$$E_{J}(\beta,\theta,K,J_{est})=\sum_{joint\ i}\gamma_{i}\omega_{i}\rho(\Pi_{K}(R_{\theta}(J(\beta))_{i})-J_{est,i}) $$
#### Variational Human Body Pose Prior
為了能夠尋找正確的全身人體姿態先驗的同時並去除不可能的人體姿態,本篇論文的作者利用 VAE 網路訓練人體的姿態先驗 __VPoser__,藉此學習人體姿態的潛在變量 $Z \in \mathbb{R}^{32}$,並使得這個潛在變量為常態分佈。

*(圖片取自 [smplx_poster.pdf (mpg.de)](https://ps.is.mpg.de/uploads_file/attachment/attachment/517/smplx_poster.pdf))*
VAE 網路的損失函數如下所示:
$$\mathcal{L}_{total} = c_{1}\mathcal{L}_{KL}+c_{2}\mathcal{L}_{rec}+c_{3}\mathcal{L}_{orth}+c_{4}\mathcal{L}_{det1}+c_{5}\mathcal{L}_{reg}$$
$$\mathcal{L}_{KL}=KL(q(Z|R)||\mathcal{N}(0,I))$$
$$\mathcal{L}_{rec}=||R-\widehat{R}||^2_2$$
$$\mathcal{L}_{orth}=||\widehat{R}\widehat{R}'-I||^2_2$$
$$\mathcal{L}_{det1}=|det(\widehat{R})-1|$$
$$\mathcal{L}_{reg}=||\phi||^2_2$$
其中 $R$ 為每一個關節 $3\times 3$ 的旋轉矩陣,並且為整個網路的輸入,$\widehat{R}$ 為同樣大小的矩陣,並且為網路的輸出。$\mathcal{L}_{KL}$為 Kullback-Leibler 項可以驅使編碼器學習潛在的變量,$\mathcal{L}_{rec}$ 可以促使潛在變量為常態分佈,並使得 VAE 網路的學習可以有效地將輸入變成輸出。$\mathcal{L}_{orth}$ 與 $\mathcal{L}_{det1}$ 可以使得潛在變量編碼成有效的旋轉矩陣。 $\mathcal{L}_{reg}$ 可以避免VAE過擬合。
#### 性別分類器
為了能夠更加準確的進行3D模型的重建,在進行重建前,會先將2D影像中的人物進行性別分類,而這個二元分類器是由 ResNet18所組成,網路的輸入為2D影像與OpenPose預測出的關節,網路的輸出會計算所屬性別的機率,當兩個性別的輸出機率皆於0.9時,則會被視為中性。

*(圖片取自 [smplx_poster.pdf (mpg.de)](https://ps.is.mpg.de/uploads_file/attachment/attachment/517/smplx_poster.pdf))*
#### 優化器
為了從目標函數中得到最佳解,本篇論文使用PyTorch與L-BFGS來進行 Wolfe 線性搜索。而整個優化過程為一個多階段的步驟,首先假設相機焦距的近似值,接著估計相機的平移與人物整體的旋轉方向,隨後固定相機參數,優化形狀參數 $\beta$ 與姿態參數 $\theta$ 。
然後按照以下三個步驟進行,從高正則化開始主要用於精煉全局身體姿態,然後逐漸增加手部關鍵點的影響以來精煉手臂姿態。在收斂到更好的姿態估計後,增加手部和面部關鍵點的影響,以捕捉表情。透過以上三個步驟,$\lambda_{\alpha}$、$\lambda_{\beta}$、$\lambda_{\mathcal{E}}$ 三個權重值會從高,逐漸遞減以得到更好的匹配,然而當手部的影響增大時,$E_{J}$ 會產生更多的碰撞,因此 $\lambda_{\mathcal{C}}$ 會逐漸增加。
### SMPLify-X 擬合的結果
下圖為二維影像經過 SMPLify-X 擬合的結果,從結果中可以清礎的了解經過 SMPLify-X 得到的 SMPL-X 模型可以清礎的呈現 2D 影像的人體姿體、臉部表情與手部姿態。

*(圖片取自 [Expressive Body Capture: 3D Hands, Face, and Body from a Single Image](https://openaccess.thecvf.com/content_CVPR_2019/papers/Pavlakos_Expressive_Body_Capture_3D_Hands_Face_and_Body_From_a_CVPR_2019_paper.pdf))*
## 應用
目前 SMPLify-X 在 GithHub 有提供開源程式碼[10],經過我們實際執行後發現了 __三項問題__。第一,作者並 __沒有提供圖形化介面__,導致執行 SMPLify-X 需透過終端機才能完成。第二,作者 __沒有將 OpenPose 與 SMPLify-X 兩個演算法進行整合__,因此要進行 SMPLify-X 演算法前,需先透過 OpenPose 找出單一 2D 影像的關鍵點,才能進一步利用作者提供的 SMPLify-X 擬合出對應的 3D 模型,導致這整個過程分成兩個步驟。第三,SMPLify-X 的作者並沒有做程式的 __例外處理__,所以當使用者給予一張 __沒有人物的影像__ 將導致 OpenPose 找不到對應的關鍵點,如果使用者沒有留意到這個問題,直接進行 SMPLify-X 會出現錯誤進而導致程式終止。
以上3種問題將導致整個 SMPLify-X 在執行上非常 __不人性化__,為了能夠解決以上的問題,我們利用 Qt[14] 來製作 __圖形化介面__,並整合了 OpenPose 與 SMPLify-X,讓使用者可以透過圖形化介面來載入需要處理的 2D 影像,並只需要透過一個按扭即可一鍵執行 OpenPose 與 SMPLify-X 得到對應的 3D 模型。除此之外,我們的應用中結合了 YOLO v4[15][16][18] 來針對輸入的 2D 影像先判斷是否有人物存在,如果偵測到有人物才能進一步執行 SMPLify-X 。以下是我們程式的執行畫面,左邊的圖片為載入的 2D 影像,右邊的影像為 SMPLify-X 所得到的 3D 模型,從得到的 3D 模型可以發現整個手部的姿態與身體形狀確實有符合 2D 影像中的畫面。

## 組員貢獻
| 組員 | 貢獻 |
| -------- | -------- |
| 邱繼群 | 論文查找、書面報告、簡報製作、論文研究、應用發想 |
| 李承澤 | 實驗測試、應用程式撰寫、應用發想、論文研究、簡報製作 |
## 參考文獻
1. [Expressive Body Capture: 3D Hands, Face, and Body from a Single Image](https://openaccess.thecvf.com/content_CVPR_2019/papers/Pavlakos_Expressive_Body_Capture_3D_Hands_Face_and_Body_From_a_CVPR_2019_paper.pdf)
2. [SMPL: A Skinned Multi-Person Linear Mode](https://dl.acm.org/doi/pdf/10.1145/2816795.2818013)
3. [Keep it SMPL: Automatic Estimation of 3D Human Pose and Shape from a Single Image](https://arxiv.org/abs/1607.08128)
4. [smplx_poster.pdf (mpg.de)](https://ps.is.mpg.de/uploads_file/attachment/attachment/517/smplx_poster.pdf)
5. [SMPLify-x 基本讲解 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/137235901)
6. [SMPL (mpg.de)](https://smpl.is.tue.mpg.de/)
7. [PowerPoint Presentation (stanford.edu)](https://web.stanford.edu/class/cs248/pdf/class_13_skinning.pdf)
8. [三維人體動捕模型 SMPL:A Skinned Multi Person Linear Model | 四一的隨寫 (yunyang1994.github.io)](https://yunyang1994.github.io/2021/08/21/%E4%B8%89%E7%BB%B4%E4%BA%BA%E4%BD%93%E6%A8%A1%E5%9E%8B-SMPL-A-Skinned-Multi-Person-Linear-Model/)
9. [Lecture-9-Skinning and Body Representations.pdf (cmu.edu)](https://www.cs.cmu.edu/~yaser/Lecture-9-Skinning%20and%20Body%20Representations.pdf)
10. [vchoutas/smplx: SMPL-X (github.com)](https://github.com/vchoutas/smplx)
11. [三维人体动捕模型 SMPL| 四一的随写](https://yunyang1994.github.io/2021/08/21/%E4%B8%89%E7%BB%B4%E4%BA%BA%E4%BD%93%E6%A8%A1%E5%9E%8B-SMPL-A-Skinned-Multi-Person-Linear-Model/)
12. [Axis–angle representation - Wikipedia](https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation)
13. [人体动作捕捉与SMPL模型 (mocap and SMPL model) - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/158700893)
14. [Qt | Tools for Each Stage of Software Development Lifecycle](https://www.qt.io/)
15. [kiyoshiiriemon/yolov4_darknet: YOLOv4 - Neural Networks for Object Detection (Windows and Linux version of Darknet ) (github.com)](https://github.com/kiyoshiiriemon/yolov4_darknet)
16. [YOLOv4 weights](https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights)
17. [SMPL-X论文学习笔记 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/419779571)
18. [YOLOv4 on OpenCV DNN (github.com)](https://gist.github.com/YashasSamaga/e2b19a6807a13046e399f4bc3cca3a49?fbclid=IwAR1S8oxu8FsrgqV5S06dKByOszROjOfLeCHE2g1pdPS-MK7paiyjOEMOte0)