想不想有一張明星臉,來看看用Python玩人臉合成!
如今,隨著技術的不斷進步, “變臉”技術不再是四川喜劇的“獨門武功”。運用機器學習的方法,我們同樣可以實現人臉“融合” 。當然這裡說的人臉融合指的是將兩個人的人臉照片進行融合,至於融合的比例,要按照自己的喜好來定。
Python學習群:556370268,有大牛答疑,有資源共享!是一個非常不錯的交流基地!歡迎喜歡Python的小夥伴!
核心原理介紹
1).首先是人臉識別的原理介紹
要進行人臉的融合,且融合後兩個人臉的位置應該大體一致,這要如何才能做到呢?首先便是人臉的檢測,只有檢測到了人臉,才能進行接下來的工作。人臉的檢測, 我們採用的是Dlib函式庫 ,幫助我們進行人臉的檢測。如下圖所示:

得到人臉的位置後,接下來就是對於人臉的關鍵點的定位,什麼是關鍵點的定位呢,說的通俗一點,就是確定圖片中人臉的關鍵特徵的位置,比如眼睛,嘴巴,鼻子的位置。而這些關鍵點又被稱為Landmark。
2).如何檢測這些關鍵點呢
這裡又利用到了Dlib庫,Dlib庫為我們提供了68個標記點的Dlib官方人臉識別模型,用於構建Dlib的特徵提取器,幫助我們進行關鍵點的提取。提取效果如下圖所示:

image
有了關鍵點,相當於我們有了兩張臉的資料,接下來我們將針對於這些關鍵點進行融合,融合的公式程式碼如下所示:
points = (1 - alpha) * np.array(points1) + alpha * np.array(points2)
其中alpha是我們的融合係數,而points1和points2分別代表兩張圖的關鍵點,points表示關鍵點融合的結果。接下來便是對points運用delaunay演算法,這個演算法將返回一個三角形列表。而至於效果則如下圖所示:

image
由上圖可以看出,兩張圖中的三角形抓取了近乎相似的區域。由上面我們可以得到圖片1中關鍵點的和圖片2中關鍵點的集合,以及合成圖片的關鍵點的集合。
我們也由delaunay演算法得到了確定的三角形。接下來我們選取圖片1中的三角形和合成圖中的三角形進行仿射變換,也就是將圖片1中的三角形對應的對映到合成圖片當中去,關於仿射變換,我們可以使用opencv中的getAffineTransform函式進行。
對於圖片2,我們也採取同樣的處理方式,最後是基於我們提供的融合係數,進行兩張人臉的融合。部分原始碼如下圖所示:

image
上述的morph_faces函式,用來進行人臉的融合,首先是讀取兩張人臉圖片,然後是獲取兩張人臉的關鍵點,分別命名為points1和points2並對points1和points2進行融合,命名為points,然後利用morph_triangle函式對人臉進行仿射變換,實現兩張人臉的對齊,並將對齊的兩張人臉按照融合係數進行融合。
軟體介面設計
以上就是關於人臉融合的基本原理,接下來就是執行介面的搭建了。
- 執行介面的搭建採用的是tkinter進行處理,
- 首先是開啟資料夾,讀入我們想要進行融合的人臉
- 然後是輸入融合的比例係數,如果我們忘記輸入融合係數的話,軟體預設的係數便是0.5
- 最後點選我們的“人臉融合”按鈕,軟體便會展示出人臉融合後的效果。
- 這裡需要注意的是,輸入的兩張圖片大小不需要嚴格的一致,程式會自動幫大家進行圖片大小的調整。

image
一共有4個按鈕,分佈是開啟圖片1,開啟圖片2,人臉融合和退出軟體。

image
中間有3張圖片,前2張都是原始圖片,最後一個合成圖片,尤其是合成圖片那裡是關鍵中關鍵:

image
這裡面的main函式是呼叫後臺的演算法函式,然後再輸入一個融合係數,就是entry.get()裡面獲取的使用者輸入的融合係數,一般預設是0.5,即兩個臉一半一半。
後臺的演算法會把兩種圖片利用cv2和dlib進行處理合成,然後生成一個新的合成圖片
最後我們用PIL庫把圖片讀出來,然後顯示在介面上即可。
看一下效果
最後,小編找了幾位明星,進行人臉的融合,效果如下圖所示:

image
這篇文章主要用了很多計算機視覺方面的庫opencv,這個庫很博大精深,幾乎玩影象的無人不知無人不曉,有興趣的同學可以研究一下。