Motivation
要製作3D動畫,在電影業界需要演員穿戴造價昂貴的追蹤裝置來記錄演員的動作,如果資金不足,你可能必須在3D繪圖軟體中手動拉出模組中的各種動作,不但耗時又費力。
因此我們思考如果能不需穿戴任何裝置,單純透過拍攝人物,得到想要的動作,並從影像中偵測出人物的動作,經過處理,然後套用到模型中製作3D動畫,不僅省時省力又省錢,也能達成製作 3D 動畫的目的,於是我們便展開專題研究。
利用2D人物動作影片,使用3D human pose estimation的技術,得到人物的動作資訊,並套用至3D人體骨架模型製作3D動畫。
要製作3D動畫,在電影業界需要演員穿戴造價昂貴的追蹤裝置來記錄演員的動作,如果資金不足,你可能必須在3D繪圖軟體中手動拉出模組中的各種動作,不但耗時又費力。
因此我們思考如果能不需穿戴任何裝置,單純透過拍攝人物,得到想要的動作,並從影像中偵測出人物的動作,經過處理,然後套用到模型中製作3D動畫,不僅省時省力又省錢,也能達成製作 3D 動畫的目的,於是我們便展開專題研究。
首先,我們輸入一段有人物動作的2D影片,為了之後的human pose estimation,我們必須先將影片切割成數個frames。
Hourglass network能將輸入的人物圖片,以heat map為輸出的方式運算出人物的關節點位置,為了使用hourglass network,前一步驟才須將輸入影片切割成frame。每個frame都會產生出對應的heat map,這時我們將frame及其對應的heat map當作輸入,進行3D human pose estimation,之後我們便可得到預測出的人物骨架動作,及其各關節點的立體座標。
得到各關節點在每個frame的立體座標後我們找一個有骨架的3D模型利用OpenGL將整個動作套在模型骨架的每個節點上產生動作
首先我們擁有一段人物行走的影片,透過matlab的程式將其切割成數個frames,並依先後順序以數字命名,例如:001, 002 , 003……。
再透過Stacked Hourglass Networks for Human Pose Estimation所提供的程式,得到每個frame相應的heat map。
切割影片frame
產生heat map
執行Sparseness Meets Deepness: 3D Human Pose Estimation from Monocular Video中提供的matlab程式,輸出預測的人體動作,我們便可在計算結果中找到人物關節點在各個frame中的立體座標。
估測出人物的16個關節點位置
接著透過我們自己寫的C++程式,處理上一步驟得到的座標資訊,轉換成3D模型所需要的格式。
在動畫的生成上,我們使用OpenGL將動畫畫出來。 並且搭配一個叫做Assimp的library幫助我們載入3D模型。
將模型載入後我們先將模型中的骨架與整個模型對好, 如此便能藉由移動骨架的節點讓模型產生動作。 之後讀取前面處理好的動作資訊,在程式中設定一個計時器根據時間決定目前的frame, 並與下一個frame的動作做內插算出目前模型的動作產生動畫。
下面為模型在對好骨架後套用模型內建動畫的樣子:
接著,我們將3D Human Pose Estimation產生的動作結果同樣用內插的方法套用到模型上。 預計模型會做出和影片中一樣的動作,然而出來的結果並非如預期般的好。
之所以不如預期我們推論有以下原因:
因此最後我們自己畫了一個火柴人將動畫展現出來
國立清華大學 資訊工程學系
王俊麒
國立清華大學 資訊工程學系
劉祥昊
This is bold and this is strong. This is italic and this is emphasized.
This is superscript text and this is subscript text.
This is underlined and this is code: for (;;) { ... }
. Finally, this is a link.
Fringilla nisl. Donec accumsan interdum nisi, quis tincidunt felis sagittis eget tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan faucibus. Vestibulum ante ipsum primis in faucibus lorem ipsum dolor sit amet nullam adipiscing eu felis.
i = 0;
while (!deck.isInOrder()) {
print 'Iteration ' + i;
deck.shuffle();
i++;
}
print 'It took ' + i + ' iterations to sort the deck.';
Name | Description | Price |
---|---|---|
Item One | Ante turpis integer aliquet porttitor. | 29.99 |
Item Two | Vis ac commodo adipiscing arcu aliquet. | 19.99 |
Item Three | Morbi faucibus arcu accumsan lorem. | 29.99 |
Item Four | Vitae integer tempus condimentum. | 19.99 |
Item Five | Ante turpis integer aliquet porttitor. | 29.99 |
100.00 |
Name | Description | Price |
---|---|---|
Item One | Ante turpis integer aliquet porttitor. | 29.99 |
Item Two | Vis ac commodo adipiscing arcu aliquet. | 19.99 |
Item Three | Morbi faucibus arcu accumsan lorem. | 29.99 |
Item Four | Vitae integer tempus condimentum. | 19.99 |
Item Five | Ante turpis integer aliquet porttitor. | 29.99 |
100.00 |