背景
坊間傳聞,當(dāng)您在房間里走動(dòng)時(shí),蒙娜麗莎的眼睛會(huì)一直盯著您。
這就是所謂的“蒙娜麗莎效應(yīng)”。興趣使然,我最近就編寫了一個(gè)可互動(dòng)的數(shù)字肖像,通過(guò)瀏覽器和攝像頭將這一傳說(shuō)變成現(xiàn)實(shí)。
這個(gè)項(xiàng)目的核心是利用 TensorFlow.js、深度學(xué)習(xí)和一些圖像處理技術(shù)。總體思路如下:首先,我們必須為蒙娜麗莎的頭部以及從左向右注視的眼睛生成一系列圖像。從這個(gè)動(dòng)作池中,我們根據(jù)觀看者的實(shí)時(shí)位置連續(xù)選擇并顯示單個(gè)幀。
TensorFlow.js
https://tensorflow.google.cn/js
接下來(lái),我將從技術(shù)層面詳細(xì)介紹該項(xiàng)目的設(shè)計(jì)和實(shí)現(xiàn)過(guò)程:
通過(guò)深度學(xué)習(xí)為蒙娜麗莎添加動(dòng)畫效果
圖像動(dòng)畫是一種調(diào)整靜止圖像的技術(shù)。使用基于深度學(xué)習(xí)的方式,我可以生成極其生動(dòng)的蒙娜麗莎注視動(dòng)畫。
具體來(lái)說(shuō),我使用了 Aliaksandr Siarohin 等人在 2019 年發(fā)布的一階運(yùn)動(dòng)模型 (First Order Motion Model, FOMM)。直觀地講,此方法由兩個(gè)模塊構(gòu)成:一個(gè)模塊用于提取運(yùn)動(dòng),另一個(gè)模塊用于生成圖像。運(yùn)動(dòng)模塊從攝像頭記錄的視頻中檢測(cè)關(guān)鍵點(diǎn)并進(jìn)行局部仿射變換 (Affine Transformation)。然后,將在相鄰幀之間這些關(guān)鍵點(diǎn)的值的差值作為預(yù)測(cè)密集運(yùn)動(dòng)場(chǎng)的網(wǎng)絡(luò)的輸入,并且用作遮擋掩模 (Occlusion Mask),遮擋掩??梢灾付ɑ蚋鶕?jù)上下文推斷需要修改的圖像區(qū)域。之后,圖像生成網(wǎng)絡(luò)會(huì)檢測(cè)面部特征,并生成最終輸出,即根據(jù)運(yùn)動(dòng)模塊結(jié)果重繪源圖像。
一階運(yùn)動(dòng)模型
http://papers.nips.cc/paper/8935-first-order-motion-model-for-image-animation.pdf
我之所以選擇 FOMM 是因?yàn)樗子谑褂?。此領(lǐng)域以前使用的模型都“針對(duì)特定目標(biāo)”:需要提供詳細(xì)的特定目標(biāo)數(shù)據(jù)才能添加動(dòng)畫效果,而 FOMM 則不需要知道這些數(shù)據(jù)。更為重要的是,這些作者發(fā)布了開箱即用的開源實(shí)現(xiàn),其中包含預(yù)先訓(xùn)練的面部動(dòng)畫權(quán)重。因此,將該模型應(yīng)用到蒙娜麗莎的圖像上就變得十分簡(jiǎn)單:我只需將倉(cāng)庫(kù)克隆到 Colab Notebook,生成一段我眼睛四處觀看的簡(jiǎn)短視頻,并將其與蒙娜麗莎頭部的屏幕截圖一起傳進(jìn)模型。得到的影片超級(jí)棒。我最終僅使用了 33 張圖片就完成了最終的動(dòng)畫的制作。
源視頻和 FOMM 生成的圖像動(dòng)畫預(yù)測(cè)示例
使用 FOMM 生成的幀示例
圖像融合
雖然我可以根據(jù)自己的目的重新訓(xùn)練該模型,但我決定保留 Siarohin 得到的權(quán)重,以免浪費(fèi)時(shí)間和計(jì)算資源。但是,這意味著得到的幀的分辨率較低,且輸出僅有主體的頭部。介于我希望最終圖像包含整個(gè)蒙娜麗莎,即包括手部、軀干和背景,我選擇將生成的頭部動(dòng)畫疊加到油畫圖像上。
頭部幀疊加到基礎(chǔ)圖像上的示例:為了說(shuō)明問(wèn)題,此處顯示的版本來(lái)自項(xiàng)目的早期迭代,其中頭部幀存在嚴(yán)重的分辨率損失
然而,這帶來(lái)了一系列難題。查看上述示例時(shí),您會(huì)發(fā)現(xiàn),模型輸出的分辨率較低(由于經(jīng)過(guò)了 FOMM 的扭曲程序,背景附帶有一些細(xì)微的更改),從而導(dǎo)致頭部幀在視覺(jué)上有突出的效果。換句話說(shuō),很明顯這是一張照片疊加在另一張照片上面。為了解決這個(gè)問(wèn)題,我使用 Python 對(duì)圖像進(jìn)行了一些處理,將頭部圖像“融合”到基礎(chǔ)圖像中。
首先,我將頭部幀重新 resize 到其原始分辨率。然后,我構(gòu)造一個(gè)新的幀,該幀的每個(gè)像素值由原圖像素和模型輸出的像素求均值后加權(quán) (alpha) 求得,離頭部中心越遠(yuǎn)的像素權(quán)值越低。
用于確定 alpha 的函數(shù)改編自二維 sigmoid,其表達(dá)式為:
其中,j 確定邏輯函數(shù)的斜率,k 為拐點(diǎn),m 為輸入值的中點(diǎn)。以下是函數(shù)的圖形表示:
我將上述過(guò)程應(yīng)用到動(dòng)畫集中的所有 33 個(gè)幀之后,得到的每個(gè)合成幀都會(huì)讓人深信不疑這就是一個(gè)圖像:
通過(guò) BlazeFace 跟蹤觀看者的頭部
此時(shí),剩下的工作就是確定如何通過(guò)攝像頭來(lái)跟蹤用戶并顯示相應(yīng)的幀。
當(dāng)然,我選擇了 TensorFlow.js 來(lái)完成此工作。這個(gè)庫(kù)提供了一組十分可靠的模型,用于檢測(cè)人體,經(jīng)過(guò)一番研究和思考后,我選擇了 BlazeFace。
BlazeFace
https://github.com/tensorflow/tfjs-models/tree/master/blazeface
BlazeFace 是基于深度學(xué)習(xí)的目標(biāo)識(shí)別模型,可以檢測(cè)人臉和面部特征。它經(jīng)過(guò)專門訓(xùn)練,可以使用移動(dòng)相機(jī)輸入。它特別適合我的這個(gè)項(xiàng)目,因?yàn)槲翌A(yù)計(jì)大部分觀看者都會(huì)以類似方式(即頭部位于框內(nèi)、正面拍攝以及非常貼近相機(jī))使用攝像頭,無(wú)論是使用移動(dòng)設(shè)備還是筆記本電腦。
但是,在選擇此模型時(shí),我最先考慮到的是它異??斓臋z測(cè)速度。為了讓這一項(xiàng)目有意義,我必須能夠?qū)崟r(shí)運(yùn)行整個(gè)動(dòng)畫,包括面部識(shí)別步驟。BlazeFace 采用 Single-Shot 檢測(cè) (SSD) 模型,這是一種基于深度學(xué)習(xí)的目標(biāo)檢測(cè)算法,在網(wǎng)絡(luò)的一次正向傳遞中可以同時(shí)移動(dòng)邊界框并檢測(cè)目標(biāo)。BlazeFace 的輕量檢測(cè)器能夠以每秒 200 幀的速度識(shí)別面部特征。
BlazeFace 在給定輸入圖像時(shí)的捕獲內(nèi)容演示:包圍人體頭部以及面部特征的邊界框
選定模型后,我持續(xù)將用戶的攝像頭數(shù)據(jù)輸入 BlazeFace 中。每次運(yùn)行后,模型都會(huì)輸出一個(gè)含有面部特征及其相應(yīng)二維坐標(biāo)位置的數(shù)組。借助此數(shù)組,我計(jì)算兩只眼睛之間的中點(diǎn),從而粗略估算出面部中心的 X 坐標(biāo)。
最后,我將此結(jié)果映射到介于 0 與 32 之間的某個(gè)整數(shù)。您可能還記得,其中的每一個(gè)值分別表示動(dòng)畫序列中的一個(gè)幀,0 表示蒙娜麗莎的眼睛看向左側(cè),32 表示她的眼睛看向右側(cè)。之后,就是在屏幕上顯示結(jié)果了。
責(zé)任編輯:lq
-
模塊
+關(guān)注
關(guān)注
7文章
2716瀏覽量
47543 -
圖像處理
+關(guān)注
關(guān)注
27文章
1293瀏覽量
56781 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5504瀏覽量
121246
原文標(biāo)題:“來(lái)自蒙娜麗莎的凝視”— 結(jié)合 TensorFlow.js 和深度學(xué)習(xí)實(shí)現(xiàn)
文章出處:【微信號(hào):tensorflowers,微信公眾號(hào):Tensorflowers】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論