【人臉辨識】你也是大眾臉嗎(average face)?

作者:曾成訓(CH.Tseng)

average face 是一項有趣的電腦視覺技術,它可以將一批不同臉孔的圖片,計算出五官的平均後顯示出來,形成一張所謂的「大眾臉」,雖然有人將其翻譯成平均臉,但個人覺得大眾臉似乎更貼切。

這個技術並不稀奇,早在 2011 年,一位南非的旅行家 Mike 就曾經把他旅遊各地所拍攝的人像合成在一起,稱為「The Faces Of Tomorrow」。

雪梨邦黛海灘(Bondi Beach, Sydney)遊客的平均臉(圖片來源:Business Insider

香港大學學生的平均臉(圖片來源:Business Insider

此外,你應該還記得前幾年曾流行一時,由不同國家人民的臉孔所平均出來的代表圖像:

(圖片來源:faceresearch.org

faceresearch.org 由蘇格蘭亞伯丁大學(the University of Aberdeen)心理學研究所所成立,是一個以臉部為主題的研究網站,當中包含了一個人臉平均的互動展示,您也可以試著玩看看。

認識 average face

透過 average face 技術,我們可以掌握如何:

  1. 偵測臉孔
  2. 取得臉部的 landmarks
  3. 取得 Delaunay_Triangulation或Voronoi_Diagrams
  4. 臉部不同區塊的合成

程式說明

下方的範例程式參考自 Satya Mallick PhD 的網路課程「Computer Vision for Faces 2018」 ,如果您有興趣,請上連結

取得 landmarks

imagePaths 為存放所有人臉的 folder,下方程式可一張張取得每張人臉的 landmarks,並放置於 allPoints,圖片內容則放置於 images。

另外,除了人臉當中的 68 個 landmarks,我們還需要加上圖片邊框上的 8 個點,這樣在最後合成人像時,才會有比較完整的大頭照,而非僅是臉部的五官區域;在原有的 68  點 landmarks 再加入 8 個點的方式是:(boundaryPoints🡪8 個新點)

New_landmarks = np.concatenate((landmark_points, boundaryPoints), axis=0)

(圖片來源:曾成訓提供)


臉孔坐標定位

normalizeImagesAndLandmarks() 這個 function 指的是參考每張臉孔的 landmarks,將各個臉部圖片依新的 landmarks 值定位於該坐標點,例如範例中左眼左上方的 landmarks 會固定於(0.3 * w, h/3),右眼右上角則位於(0.7 * w, h / 3),其中 w、h 指的是最終輸出圖片的寬與高。

function:normalizeImagesAndLandmarks

最終定位好的 72 個 landmarks(含邊框 8 個)以及臉部圖片,放置於 pointsNorm 以及 imagesNorm。

取得 delaunay 三角剖分區域

calculateDelaunayTriangles function 只需要輸出圖的 shape 以及定位點 list,便可輸出其 delaunay triangulation areas。

dt = fbc.calculateDelaunayTriangles(rect, pointsAvg)

function: calculateDelaunayTriangles

合成臉部圖片

output 為輸出的最終圖片,而 warpImage function 在輸入了原圖、原 landmarks、定位後的 landmarks 以及上一步所取得的 dt(delaunay triangulation)資訊後,便能將原圖的各個 delaunay triangulation area 變形為定位後的 delaunay triangulation area,最後再將每張變形後的 delaunay triangulation area 拼接回臉部圖形,即完成。

此 function 針對輸入 delaunay point list 進行變形:

區塊變形指令使用的是 cv2.estimateRigidTransform,但要注意,目前版本的 OpenCV 已不支援,須改用cv2.estimateAffinePartial2D 來替代。

tform = cv2.estimateRigidTransform(np.array([inPts]), np.array([outPts]), False)

改為

tform,_ = cv2.estimateAffinePartial2D(np.array([inPts]), np.array([outPts]))

輸入前後兩種 point list,回傳的 tform 就是 cv2.warpAffine的affine transformation 參數。

imOut = cv2.warpAffine(imIn, tform, (w, h))

小結

大家猜猜這兩位是誰?

(圖片來源:曾成訓提供)

實際上並不存在這兩個人,他們是由下面這些公司男女同仁平均而成的臉:

(圖片來源:曾成訓提供)

(圖片來源:曾成訓提供)

(圖片來源:曾成訓提供)

由於合成的臉部是經過校準及對稱的,因此這種對齊後的五官組合起來通常讓人感覺端正美觀,也就是符合一般人所稱的俊男美女的特色。

(本文經作者同意轉載自 CH.TSENG 部落格、原文連結;責任編輯:賴佩萱)

曾 成訓

人到中年就像沒對準的描圖紙,一點一點的錯開,我只能當個Maker來使它復位。
曾 成訓

Author: 曾 成訓

人到中年就像沒對準的描圖紙,一點一點的錯開,我只能當個Maker來使它復位。

Share This Post On

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *