標籤:

如何用SphereFace+純Python刷分Megaface

SphereFace 是今年CVPR的一篇論文, 理論直觀優美, 作者的代碼和調參功力也足夠深厚. 已經有部分人用項目中release的20層模型在Megaface-challenge-1中刷到了70%以上的準確率. 例如Normface作者.

但目前看到的代碼都是基於matlab的, 對python黨來說不夠友好. 下面說一下如何用純python復現.

其中最關鍵的一步是如何用python做人臉對齊. 參照這裡的方法, 對齊大概分以下幾步:

  1. 用MTCNN檢測圖片的人臉區域和關鍵點(5個,眼睛*2,鼻子,嘴角*2)
  2. 如果有多個人臉區域, 計算這些人臉區域與數據源標定區域的IoU, 取最大的.
  3. 如果未檢測到任何人臉區域, 兩種方案:
    1. 對標定區域降低閾值強制檢測人臉.
    2. 直接對圖片取center crop.

MTCNN檢測用Matlab或者python版本問題都不大. 重點是檢測到關鍵點後如何對齊?

對齊在matlab中對應的函數是cp2tformimtransform. cp2tform獲取兩組坐標之間的2D變換參數. imtransform 利用參數轉換圖像並切割到固定大小.

先看一下例子, 以下是原圖(取自facescrub, image_id:14680):

用MTCNN+matlab cp2tform+ imtransform 對齊後:

可以看到效果不錯.

然後我們試幾個python實現,

1. 全仿射變換:

src = np.array([ [30.2946, 51.6963], [65.5318, 51.5014], [48.0252, 71.7366], [33.5493, 92.3655], [62.7299, 92.2041] ], dtype=np.float32 )dst = mtcnn_landmark.astype(np.float32)M = cv2.estimateRigidTransform( dst.reshape(1,5,2), src.reshape(1,5,2), True)warped = cv2.warpAffine(img,M,(shape[1],shape[0]), borderValue = 0.0)

效果如下,有點失真:

2. 再來帶約束的仿射變換:

M = cv2.estimateRigidTransform( dst.reshape(1,5,2), src.reshape(1,5,2), False)warped = cv2.warpAffine(img,M,(shape[1],shape[0]), borderValue = 0.0)

效果如下,好一些, 也能用了, 但是和matlab的版本還是不一樣(旋轉角度有區別). 因為作者提供的模型是用matlab的對齊演算法訓練的, 所以我們必須和他保持一致.

3.繼續, 相似變換, 用skimage的similarity transform:

from skimage import transform as transtform = trans.SimilarityTransform() tform.estimate(dst, src)M = tform.params[0:2,:]warped = cv2.warpAffine(img,M,(shape[1],shape[0]), borderValue = 0.0)

效果, 基本和matlab一致, 除了縮放比例有一些細微的差別, 但應該不影響測試了.

對齊後的測試方法就比較簡單了, 用對齊後的人臉及其翻轉鏡像送入caffe模型得到向量相加, 並歸一化做為特徵.

測試結果(Megaface challenge-1 Top-1 Accuracy):

  1. 全仿射變換: 44%.
  2. 帶約束的仿射變換: 47%.
  3. skimage similarity transform: 69.5%.

檢測及對齊部分還有提高空間.

ps: 如果訓練時就用第一(?)或者第二種對齊方法的話, 可能最終準確率差不了多少.

下一步就是自己訓練模型了.


推薦閱讀:

【AI美顏演算法】300行Python實現基於人臉特徵的美顏演算法
眼球追蹤技術,可用於操作瀏覽器等,你有什麼創意或看法?
[開源] 一個機器翻譯平台 + 一個人臉識別平台
C# 實現人臉識別一 (運用虹軟人臉識別引擎)

TAG:人脸识别 |