本身動手製做「平均臉」【1】


有趣的「平均臉」


你們想必看到過不少合成的「平均臉」圖片吧。


有按國家、民族合成的:



也有針對政要明星合成的,例如這張,韓中日三國明星平均臉:html



「平均臉」的歷史python


雖然如今很流行,可是,其實平均臉的歷史至關悠久。git


1878年,英國的弗朗西斯·高爾頓爵士(Sir Francis Galton)發明了一種創造出「平均」面容的技術。github


弗朗西斯·高爾頓爵士,英國維多利亞時代的博學家、人類學家、優生學家、熱帶探險家、地理學家、發明家、氣象學家、統計學家、心理學家和遺傳學家;也是《物種起源》做者查爾斯·達爾文的表弟。*web

這一方法是經過將許多人的照片合成爲一張照片完成的。微信

當時具體的作法是:照片疊加——給多我的,好比20我的,照相,將每一個人照片所需的曝光時間縮短爲1/20,經過20次曝光獲得一張「平均」照片。spa

弗朗西斯·高爾頓最初合成平均臉的目的是將不一樣「種類」的人(例如:囚犯、精神病患者等等)視覺化,以期獲得這類人的「原型」(共同特徵)。.net

但結果卻意外的發現,這樣合成的人臉卻比用於合成大部分(甚至是所有)都要好看!orm

雖然高爾頓爵士的初衷沒有達到,合成平均臉的方法卻保留了下來。htm

新技術讓人人可製做「平均臉」

隨着技術的發展,照片再也不須要物理底片,合成也再也不須要複雜的曝光沖印技術,經過一些簡單的操做就能作到,人人均可以上手。

想不想本身動手製做一張周圍人的平均臉?

一點都不復雜,只要知道了用Image Morphing技術疊加照片原理,再會寫幾行簡單的代碼,就能順利完成。

Image Morphing技術的原理至關簡單:給定兩張圖片I和J,咱們經過疊加(或者叫作混合)I和J來得到一張中間狀態的圖片M。

I和J的疊加由一個參數[0,1]區間內的參數alpha來控制。當alpha=0時,M就等同於I,而aphla=1時,M就爲J。

換言之, M中的每個像素M(x,y),均可以經過這樣一個公式來獲得它的值:

M(x,y) = (1 – alpha)·I(x,y) + alpha·J(x,y)

當alpha=0.5的時候,I和J就五五開,平均貢獻了M。若是I和J是兩張人臉照片的話,M天然也就成了它們的「平均臉」。

看起來好容易哦,那咱們趕忙找兩張照片來試試吧!就用這兩張:

這兩張照片alpha=0.5後直接疊加的結果是這樣的:

這也不是人臉呀!先別急,看看爲何會這樣?

從這張「重影圖」上不難看出來,之因此這樣,是由於最基本的五官都沒有對齊。

若是咱們事先把兩我的的眼睛和嘴對齊,效果就不會是這樣的了。

疊加兩張*對齊的*人臉

疊加圖片I和圖片J的時候,首先應該創建兩張照片中像素的對應關係


對I中的某一個像素點(xi,yi),咱們不是直接在J中取一樣位置的點就能夠了,而是要找到它在J中內容上的對應點 (xj,yj)。


而後再進一步找到M中這兩個點疊加以後應當處在的位置(xm,ym),最後再用下列式子得出M中對應點的像素值:


xm = (1-alpha) · xi + alpha · xj

ym = (1-alpha) · yi + alpha · yj

算式-1

對一個像素點咱們這樣作,對整幅圖片,則是將上面的過程運用到它的每個像素點上:

M(xm,ym) = (1 – alpha)·I(xi,yi) + alpha·J(xj,yj)

算式-2

很好,咱們已經知道從原理上該怎麼疊加兩張圖了。

其中關鍵的一步就是:找到對應點

其實對應點疊加的方法能夠用來疊加任何圖片,不只限於人臉。

不一樣物體的疊加,真正的區別就在於找到像素點之間的對應關係!一旦對應關係找到,直接運用算式-2就行了。

劃分區域對應人臉

既然咱們如今要作的是疊加人臉,那麼首先固然要找到人臉上的對應點。

人臉是生活中最多見的事物,咱們每個人都很是熟悉。

一我的的臉若是用簡筆畫畫出來,能夠簡化爲:臉型+五官(眉毛、眼睛、鼻子、嘴)。

那麼若是咱們要疊加兩我的的臉的話,天然就是要針對他們的臉型和五官形制求平均。

人的五官若是用圖形來描繪,都是不規則圖形。若是要徹底不走樣的獲取一我的的眼睛、眉毛、鼻子或者嘴,須要繪製很是複雜的形狀。

實際上,咱們沒有必要這樣作,而是能夠經過一種很是簡單的近似方法,把一張人臉分割成若干三角形的區域,而後再來疊加兩張臉上對應的三角區域。

分割方法以下:

1. 獲取人臉特徵


在圖片中獲取人臉和人臉特徵(臉型+五官)。

咱們先在每張面孔上獲取68個面部基準點(以下圖)。


2. Delaunay 三角剖分


在得到了68個面部基準點以後,咱們結合人臉所在的矩形的四個頂點和每條邊的中心點,將人臉所在的矩形分割成以下圖所示的三角形的組合。


這一方法又稱爲Delaunay三角剖分。更多細節請看:https://www.learnopencv.com/delaunay-triangulation-and-voronoi-diagram-using-opencv-c-python/

疊加通過仿射變換的Delaunay剖分三角形


Delaunay三角剖分將圖像分解成若干三角形後,再分別對齊各個三角形區域,對其中像素值進行平均。


Step-1:找到合成圖片中的面部特徵點

使用前述的算式-1,根據圖像I和圖像J中已經得到的76個點,在疊加的結果圖像M中找到76個點(xm, ym)

Step-2: 計算原圖到目標圖像的仿射變換

如今咱們在圖像I,J和M中分別獲得了76個點,以及由這76個點剖分而成的三組三角形。

從圖像I中選取一個三角形ti,在M中找到對應區域tm,經過ti三個頂點到tm三個頂點的映射關係來計算ti到tm的仿射變換。

同理計算出tj到tm的仿射變換。

Step-3:扭曲Delaunay剖分三角形

對於圖像I中的一個三角形,使用step-2中計算出的放射變換,將其中每個像素經過仿射變換對應到M中對應的位置去。

重複這個過程,處理圖像I中的每個三角形,獲得一個扭曲的(warped)圖像I'。用一樣的方法處理圖像J,得到扭曲的圖像J'。

Step-4:疊加兩張臉

在step-3中咱們已經獲得了扭曲的圖像I'和圖像J'。這兩個圖像就能夠直接使用算式-2進行疊加了。最後獲得疊加結果。

疊加多張人臉


算式-2用於疊加2張人臉,在alpha=0.5時求取的是兩張臉的平均。

那麼咱們把算式推廣一下,從圖像I和圖像J推廣爲圖像I1, I2, I3, ..., In;令alpha=1/n;則算式-2變形爲以下:

M(xm,ym) = 1/n · [I1(xi1, yi1) + I2(xi2, yi2) + ... ... + In(xin, yi_n)]

由此,咱們也就獲得了n張臉的平均。

用這個方法,咱們能夠獲得6位美國總統的平均臉:

他們平均以後的樣子是這樣的:

上面的過程看着還挺複雜是否是?其實,若是使用opencv + dlib,只要幾十行代碼就能搞定!

今天先講原理,下次咱們再來分析具體技術和代碼 

代碼在此:https://github.com/juliali/AverageFace

歡迎掃面下列二維碼關注「悅思悅讀」公衆微信號

本文分享自微信公衆號 - 悅思悅讀(yuesiyuedu)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索