無需人臉檢測,即可實時,6自由度3維人臉姿態估計方法 | 代碼剛開源

2021-02-16 AIWalker

摘要我們提出了實時、六自由度(6DoF)、三維人臉姿態估計,無需人臉檢測或關鍵點定位。我們發現估計人臉的6自由度剛性變換比人臉關鍵點檢測更簡單,人臉關鍵點檢測通常用於三維人臉對齊。此外,6DoF提供了比人臉框標籤更多的信息。我們利用這些觀察結果做出了多種貢獻:(a)我們描述了一個容易訓練、高效、基於Faster R-CNN的模型,該模型回歸照片中所有面孔的6DoF姿態,而不需要進行初步的人臉檢測。(b)我們解釋在訓練和評估我們的模型時,如何轉換輸入照片和任意作物之間的姿態並保持一致。(c)最後,我們展示了人臉姿態如何取代檢測邊界框訓練標籤。在AFLW2000-3D和BIWI上的測試表明,我們的方法運行在實時和性能優於狀態(SotA)人臉姿態估計器。值得注意的是,我們的方法在更寬的人臉檢測基準上也超過了類似的SotA模型,儘管沒有在包圍框標籤上進行優化。1、簡介


人臉檢測就是定位一個框,把一張照片中的每一張人臉框起來起來。人臉關鍵點檢測旨在定位特定的面部特徵:例如,眼睛中心,鼻尖。

儘管這種方法對過去而言是成功的,但它也有缺點。關鍵點檢測器通常能優化到由特定的人臉檢測器產生的邊界框的特性(上限)。更新人臉檢測器也需要重新優化關鍵點檢測器。此外,SotA 的檢測和姿態估計需要巨大的計算量。最後一點,對於定位標準的68個關鍵點而言,小臉是非常難做到的。

為了解決上述的問題,我們重點關注了下面的內容:

關注點1:估計6個姿態自由度比檢測關鍵點更容易

關注點2:6個姿態自由度標籤捕捉的不僅僅是框的位置。

貢獻:

我們提出了一種直接對圖像中所有人臉進行6自由度三維人臉姿態估計的新方法,而不需要進行人臉檢測

我們介紹了一種有效的姿態轉換方法,以保持估計和真實位姿的一致性,在圖像和它的特別推薦之間

我們展示了生成的3D姿態估計如何被轉換成精確的2D邊界框,能作為附帶產物,以最小的計算開銷。

我們的模型使用了一個小的、快速的ResNet-18 作為 backbone,並在WIDER FACE 訓練集上使用弱監督和人工注釋的ground-truth姿態標籤進行訓練。

2、Related work

主要涉及 Face detection

Face alignment and pose estimation

這裡不詳細介紹了,文章介紹了一些相關工作的最新進展。

之前的人臉識別綜述中有涉及到一些相關的,感興趣的可以參看下面的連結

2020人臉識別最新進展綜述,參考文獻近400篇 | 附下載

3、本文提出的方法


給定一張圖片 I,估計圖片中每個人臉的6 個自由度。

其中的含義:

(rx, ry, rz) 表示 Euler angles – roll, pitch, yaw 旋轉

(tx, ty, tz)是三維人臉變換

3.1. Our img2pose network

網絡採用 圖 4 的 基於 Faster R-CNN 的二階段方法。第一階段採用的是特徵金字塔的 RPN 網絡,用於定位在圖片可能存在人臉的位置。

與標準的RPN loss不同(採用ground-truth 邊界框),我們對邊界框進行投影,採用方程 2 獲得6個姿態自由度的ground-truth 姿態標籤。能獲得更好人臉區域一致性。

K是內參矩陣

R和t分別為由h得到的三維旋轉矩陣和平移向量均值

是一個表示三維面形曲面上n個三維點的矩陣。

最後,是二維點從三維投影到圖像上的矩陣表示。

其他地方與 Faster R-CNN類似。

我們的img2pose的第二階段從每個proposal 中提取具有感興趣區域(ROI)池化的特徵,然後將它們傳遞給兩個不同的頭部:一個標準的人臉/非人臉分類器和一個新穎的6自由度人臉姿態回歸器

3.2. Pose label conversion

簡單地說,算法1有兩個步驟。首先,在第2-3行,我們調整姿勢。這一步直觀地調整相機來查看整個圖像,而不僅僅是一個裁剪。然後,在步驟4-8中,我們轉換焦點,根據焦點位置的差異調整裁剪和圖像之間的姿態。最後,我們返回一個相對於圖像本身 Kimg 的6自由度姿態。

3.3. Training losses

我們同時訓練了人臉/非人臉分類器的頭部和人臉姿態回歸器。對於每個proposal,模型採用以下多任務損失L。

(1)Face classification loss.

使用標準二進位交叉熵損失(cross-entropy loss)

(2)Face pose loss

這一損失直接比較了6自由度人臉姿態估計與其ground-truth

(3)Calibration point loss

這是一種獲取估計姿態精度的額外手段,我們考慮在圖像中投影的3D臉形點的二維位置

4、應用細節

img2pose network

我們提出了一種新的六自由度人臉姿態估計和對齊方法,它不依賴於首先運行人臉檢測器或定位人臉標誌。據我們所知,我們是第一個提出這種多面、直接的方法的人。我們提出了一種新的姿態轉換算法,以保持在不同圖像中對同一人臉的位姿估計的一致性。我們證明了通過估計的三維人臉姿態可以產生人臉框,從而實現了作為姿態估計的副產品的人臉檢測。大量的實驗證明了我們的img2pose對於人臉姿態估計和人臉檢測的有效性。

作為一個類,人臉作為姿態和檢測的結合提供了很好的機會:面孔有明確的外觀統計,可以依賴於準確的姿態估計。然而,臉並不是可以採用這種方法的唯一類別;在其他領域,例如零售[25],通過應用類似的直接姿態估計步驟來替代目標和關鍵點檢測,也可以獲得同樣的精度提高。

5、代碼試跑

使用官方提供的模型和數據集測試姿態估計和對齊效果

import syssys.path.append('../../')import numpy as npimport torchfrom torchvision import transformsfrom matplotlib import pyplot as pltfrom tqdm.notebook import tqdmfrom PIL import Image, ImageOpsimport matplotlib.patches as patchesfrom scipy.spatial.transform import Rotationimport pandas as pdfrom scipy.spatial import distanceimport timeimport osimport mathimport scipy.io as sioimport randomfrom utils.renderer import Rendererfrom utils.image_operations import expand_bbox_rectanglefrom utils.pose_operations import get_posefrom img2pose import img2poseModelfrom model_loader import load_modelfrom data_loader_lmdb import LMDBDataLoaderfrom dataclasses import dataclass
np.set_printoptions(suppress=True)
torch.random.manual_seed(42)np.random.seed(42)
@dataclassclass Config: batch_size: int pin_memory: bool workers: int pose_mean: np.array pose_stddev: np.array noise_augmentation: bool contrast_augmentation: bool threed_68_points: str distributed: boolrenderer = Renderer( vertices_path="pose_references/vertices_trans.npy", triangles_path="pose_references/triangles.npy")
threed_points = np.load('pose_references/reference_3d_68_points_trans.npy')
transform = transforms.Compose([transforms.ToTensor()])
BBOX_X_FACTOR = 1.1BBOX_Y_FACTOR = 1.1EXPAND_FOREHEAD = 0.3
DEPTH = 18MAX_SIZE = 1400MIN_SIZE = 600
POSE_MEAN = "models/WIDER_train_pose_mean_v1.npy"POSE_STDDEV = "models/WIDER_train_pose_stddev_v1.npy"MODEL_PATH = "models/img2pose_v1.pth"
pose_mean = np.load(POSE_MEAN)pose_stddev = np.load(POSE_STDDEV)
img2pose_model = img2poseModel( DEPTH, MIN_SIZE, MAX_SIZE, pose_mean=pose_mean, pose_stddev=pose_stddev, threed_68_points=threed_points, bbox_x_factor=BBOX_X_FACTOR, bbox_y_factor=BBOX_Y_FACTOR, expand_forehead=EXPAND_FOREHEAD,)load_model(img2pose_model.fpn_model, MODEL_PATH, cpu_mode=str(img2pose_model.device) == "cpu", model_only=True)img2pose_model.evaluate()

LMDB_FILE = "datasets/lmdb/WIDER_val_annotations.lmdb"
lmdb_data_loader = LMDBDataLoader( Config( batch_size=1, pin_memory=True, workers=1, pose_mean=pose_mean, pose_stddev=pose_stddev, noise_augmentation=False, contrast_augmentation=False, threed_68_points='pose_references/reference_3d_68_points_trans.npy', distributed=False ), LMDB_FILE, train=True,)
threshold = 0.8total_imgs = 20
data_iter = iter(lmdb_data_loader)
for j in tqdm(range(total_imgs)): torch_img, target = next(data_iter) target = target[0] bboxes = [] scores = [] poses = [] img = torch_img[0] img = img.squeeze() img = transforms.ToPILImage()(img).convert("RGB") ori_img = img.copy()
run_img = img.copy()
w, h = img.size
min_size = min(w, h) max_size = max(w, h) img2pose_model.fpn_model.module.set_max_min_size(max_size, min_size)
res = img2pose_model.predict([transform(run_img)])
res = res[0]
for i in range(len(res["scores"])): if res["scores"][i] > threshold: bboxes.append(res["boxes"].cpu().numpy()[i].astype('int')) scores.append(res["scores"].cpu().numpy()[i].astype('float')) poses.append(res["dofs"].cpu().numpy()[i].astype('float')) (w, h) = img.size image_intrinsics = np.array([[w + h, 0, w // 2], [0, w + h, h // 2], [0, 0, 1]]) plt.figure(figsize=(16, 16)) poses = np.asarray(poses) bboxes = np.asarray(bboxes) scores = np.asarray(scores) print(poses) if np.ndim(bboxes) == 1 and len(bboxes) > 0: bboxes = bboxes[np.newaxis, :] poses = poses[np.newaxis, :] if len(bboxes) != 0: ranked = np.argsort(poses[:, 5])[::-1] poses = poses[ranked] bboxes = bboxes[ranked] scores = scores[ranked]
for i in range(len(scores)): if scores[i] > threshold: bbox = bboxes[i]
pose_pred = poses[i] pose_pred = np.asarray(pose_pred.squeeze())
trans_vertices = renderer.transform_vertices(img, [pose_pred]) img = renderer.render(img, trans_vertices, alpha=1) plt.gca().add_patch(patches.Rectangle((bbox[0], bbox[1]), bbox[2] - bbox[0], bbox[3] - bbox[1],linewidth=3,edgecolor='b',facecolor='none')) img = Image.fromarray(img)
plt.imshow(img) plt.show()

輸入圖片:

對齊後的效果:

更多的細節可以參看論文和官方的開原始碼。公式推導等附錄有一些介紹。

如果文章對你有所幫助,請給一波三連(關注,點讚,在看),感謝

連結:https://arxiv.org/abs/2012.07791

代碼:http://github.com/vitoralbiero/img2pose

相關焦點

  • Facebook等提出實時3D人臉姿態估計新方法,代碼已開源!
    自由度的實時 3D 人臉姿態估計技術,可以不依賴人臉檢測和人臉關鍵點定位獨立運行。為了解決這些問題,來自 Facebook AI 和聖母大學的研究者提出了以下重要觀察結果:首先,估計人臉的 6 自由度(6DoF)剛性變換比人臉關鍵點檢測要簡單。
  • 跳過人臉檢測和關鍵點定位,Facebook等提出實時3D人臉姿態估計新方法
    來自 Facebook AI 和美國聖母大學的研究者提出了一種 6 自由度的實時 3D 人臉姿態估計技術,可以不依賴人臉檢測和人臉關鍵點定位獨立運行
  • 【附完整代碼:AI實戰】動手編寫人臉識別
    檢測人臉有很多種方式,下面介紹幾種常用的方法:(1)使用OpenCV檢測人臉OpenCV中自帶了人臉檢測器,基於Haar算法進行人臉檢測。FaceNet是谷歌發布的人臉檢測算法,發表於CVPR 2015,這是基於深度學習的人臉檢測算法,利用相同人臉在不同角度、姿態的高內聚性,不同人臉的低耦合性,使用卷積神經網絡所訓練出來的人臉檢測模型,在LFW人臉圖像數據集上準確度達到99.63%,比傳統方法的準確度提升了將近30%,效果非常好。
  • 人臉關鍵點檢測
    在人臉識別技術中是人臉檢測的下一步任務。關鍵點檢測基礎人臉關鍵點檢測是指給定人臉圖像,定位出人臉面部的關鍵點,包括眉毛、眼睛、鼻子、嘴、臉部輪廓區域的點,由於受到姿態和遮擋等因素的影響,關鍵點檢測是一個富有挑戰性的任務。
  • 六種人體姿態估計的深度學習模型和代碼總結
    姿態估計的目標是在RGB圖像或視頻中描繪出人體的形狀,這是一種多方面任務,其中包含了目標檢測、姿態估計、分割等等。有些需要在非水平表面進行定位的應用可能也會用到姿態估計,例如圖形、增強現實或者人機互動。姿態估計同樣包含許多基於3D物體的辨認。在這篇文章中,Model Zoo的作者匯總了幾種開源的深度學習模型以及針對姿態估計的代碼,論智對其進行了編譯,如有遺漏請在評論中補充。
  • 40個姿態估計優秀開源項目匯總
    實時全身多人姿勢估計與跟蹤系統。它是第一個開源系統,在COCO數據集上達到70+ mAP(75 mAP),在MPII數據集上達到80+ mAP(82.1 mAP)。為了在幀中匹配與同一個人相對應的姿勢,還提供了一種稱為Pose Flow的高效在線姿勢跟蹤器。
  • 人體姿態估計的過去,現在,未來
    同時,如果把人體姿態往3D方面進行擴展,輸入RGB圖像,輸出3D的人體關鍵點的話,就是3D 人體姿態估計。這個有一個經典的數據集Human3.6M。最近,除了輸出3D的關鍵點外,有一些工作開始研究3D的shape,比如數據集DensePose。長線來講,這個是非常有價值的研究方向。3D人體姿態估計的結果圖(來自算法a simple baseline)如下:
  • 計算機視覺方向簡介 | 人體姿態估計
    多人姿態估計由於不知道圖像中每個人的位置和總人數,因此多人姿態估計比單人姿態估計更困難。通常,我們可以通過以下方法來解決上述問題:簡單的方法是:首先加入一個人體檢測器,然後分別估計各個部件,最後再計算每個人的姿態。這種方法被稱為「自頂向下」的方法。
  • MediaPipe 集成人臉識別,人體姿態評估,人手檢測模型
    ,此模型最主要的優點是不需要我們下載預訓練模型,只是安裝上其mediapipe包即可  )results=holistic.process(image)  模型檢測完成後的結果保存在results裡面,我們需要訪問此結果,並把檢測到的人臉,人手,以及姿態評估的數據點畫在原始檢測的圖片上,以便查看  ifresults.pose_landmarks:print(f'Nosecoordinates:('f'{results.pose_landmarks.landmark
  • Python 實現人臉檢測並不難,50 行代碼搞定!
    用iPhone的同學們應該對下面的功能比較熟悉iPhone的照片中有一個「人物」的功能,能夠將照片裡的人臉識別出來並分類,背後的原理也是人臉識別技術。這篇文章主要介紹怎樣用Python實現人臉檢測。人臉檢測是人臉識別的基礎。人臉檢測的目的是識別出照片裡的人臉並定位面部特徵點,人臉識別是在人臉檢測的基礎上進一步告訴你這個人是誰。
  • 涵蓋15個方向:目標檢測/圖像處理/姿態估計/醫學影像/人臉識別等方向
    加白噪聲圖像的CNN;(2)用於真實噪聲圖像的CNN;(3)用於盲噪聲去噪的CNN;(4)用於混合噪聲圖像的CNN。圖像分割標題:Image Segmentation Using Deep Learning: A Survey作者:Shervin Minaee, Demetri Terzopoulos連結:https://arxiv.org/abs/2001.05566本文梳理了172篇相關文獻,對語義和實例分割文獻進行了全面回顧,涵蓋了的各種開創性作品
  • WACV 2021 論文大盤點-姿態估計篇
    本篇繼續總結姿態估計相關論文, 3D 的佔大多數,有 3D 姿勢、形狀估計,還有 3D 手部姿勢估計。還有人臉姿態估計、跨物種姿態估計等。
  • 模型僅有7M:輕量級高精度人臉識別方法DBFace
    DBFace 是一個輕量級的實時人臉識別方法,其有著更快的識別速度與更高的精度。下圖展示了多種人臉檢測方法在 WiderFace 數據集上的測試效果。可以看到不僅 DBFace 模型的大小最小,其在 Easy、medium、Hard 三個測試任務中均取得了最高的識別精度。
  • 用於類別級物體6D姿態和尺寸估計的標準化物體坐標空間
    另一方面,類別級別的3D對象檢測方法[43、36、9、34、49、12]可以估計對象類別標籤和3D邊界框,而無需精確的CAD模型。但是,估計的3D邊界框取決於視點,並且不對對象的精確方向進行編碼。因此,這兩種方法都無法滿足需要6D姿態和3個非均勻縮放參數(編碼尺寸)的未見過對象的應用程式的要求。
  • 迄今最精準人臉數字模型,任意 2D 照片轉換逼真3維人臉
    目前為止所採用的方法是掃描大量人臉,然後人工仔細標記所有的特徵。也因此,目前最好的模型也只是基於幾百張人臉——大部分還都是白人,而且模型在模仿不同年齡和種族人臉方面的能力十分有限。 現在,倫敦帝國理工學院(ICL)的計算機科學家 James Booth 和同事開發了一種新的方法,可以自動構建 3DMM,並使其能夠融入更廣泛的人臉,比如不同種族的特徵。
  • 用Python進行人臉識別「包括原始碼」
    我們在項目中使用了人臉識別API和OpenCV。隨時了解最新的技術趨勢加入DataFlair的電報!工具與圖書館Python-3.xCV2-4.5.2矮胖-1.20.3人臉識別-1.3.0若要安裝上述軟體包,請使用以下命令。
  • 【人臉技術原理】(三)人臉關鍵點檢測(PFLD算法)
    人臉關鍵點檢測基礎知識人臉關鍵點檢測也稱為人臉關鍵點檢測、定位或者人臉對齊,是指給定人臉圖像,定位出人臉面部的關鍵區域位置,包括眉毛、眼睛、鼻子、嘴巴、臉部輪廓等和人臉檢測類似,由於受到姿態和遮擋等因素的影響
  • 教你用OpenCV人臉檢測自動給頭像戴聖誕帽(附代碼)
    本文長度為3400字,建議閱讀7分鐘跟著代碼走,教你自動給頭像帶上聖誕帽
  • 涵蓋15個方向:目標檢測/圖像處理/姿態估計/醫學影像/人臉識別等方向
    、圖像分類、圖像去噪、圖像分割、人臉識別、姿態估計、醫學影像等15個方向,文末提供這25篇論文打包好的下載途徑。討論多種異常實例檢測方法,並分析了各種方法的相對優勢和劣勢。(包括DeepFake方法)以及檢測此類技術的方法進行了全面綜述。
  • FaceBoxes—官方開源CPU實時高精度人臉檢測器
    收錄於話題 #52CV-人臉技術 點擊我愛計算機視覺標星,更快獲取CVML新技術近日FaceBoxes算法的提出者開源了該算法所有訓練和測試代碼,並提供Caffe與PyTorch