創建基于臉型的AR體驗


翻譯完了才發現已經有人翻譯過了,而且還是自己收藏過的,服了自己了。
不過蘋果的文檔也有些許更新,也總算是過了一遍,大家隨意看看,有示例代碼運行效果截圖,整體效果還是不錯的。ps:iPhone X也是不錯的??。


原文 Creating Face-Based AR Experiences

使用iPhone X上的TrueDepth相機來根據用戶臉型放置3D內容,并根據用戶表情做動畫。
下載官網demo

SDKs
iOS 11.0+
Xcode 9.1+

概述

這個示例app展示了一個簡單的界面,讓你可以在擁有TrueDepth 前置相機的設備(iPhone X)上選擇4種AR特效。

  • 只有相機拍攝的視圖,沒有AR特效。
  • ARKit 提供的臉部網格(mesh),并提供自動的現實世界光線感知環境。
  • 貼在用戶臉上的虛擬3D內容。
  • 一個簡單的機器人形象,面部表情會跟用戶一致。

用示例app中的"+"按鈕來選擇不同的效果,如下圖所示。


使用SceneKit視圖來新建一個臉部追蹤Session

跟其他ARKit的應用一樣,臉部追蹤需要配置并運行一個session(一個ARSession對象),并在同一個視圖里同時渲染相機圖像和虛擬內容。如需更多關于session和view的詳細教程,參考 About Augmented Reality and ARKit Building Your First AR Experience。這個示例使用SceneKit來顯示AR體驗,你也可以用SpriteKit 或者用Metal來創建你自己的渲染器(參考ARSKViewDisplaying an AR Experience with Metal)。

臉部追蹤跟其他ARKit的應用的不同之處在于配置session的所使用的類不同。要使用臉部追蹤,你得創建一個ARFaceTrackingConfiguration的實例,配置一下它的屬性,然后傳給view的AR session的run(_:options:)方法,如下:

// 判斷是否支持FaceTracking
guard ARFaceTrackingConfiguration.isSupported else { return }
// 創建配置類
let configuration = ARFaceTrackingConfiguration()
configuration.isLightEstimationEnabled = true
// run
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])

追蹤臉部的位置和旋轉

當臉部追蹤激活的時候,ARKit自動向正在運行的AR session中添加ARFaceAnchor
對象,此對象包含用戶臉部的位置和旋轉信息。

提示

ARKit 只能檢測和提供以為用戶的臉部。如果攝像頭捕捉到多個臉,ARKit會挑選最大或者最能清晰分辨的臉部來識別。

在使用基于SceneKit的AR體驗時,你可以在renderer(_:didAdd:for:)方法(遵循ARSCNViewDelegate協議)添加一個可以響應臉部錨點的3D物件。ARKit會在錨點上添加一個SceneKit節點(node),并在每一幀更新node的位置和旋轉屬性,因此你添加在這個節點上的任意SceneKit內容都會自動跟隨用戶臉部的位置和旋轉運動。

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    // Hold onto the `faceNode` so that the session does not need to be restarted when switching masks.
    // 持有`faceNode`可以在換面具時不需要重啟session
    faceNode = node
    serialQueue.async {
        self.setupFaceNodeContent()
    }
}

在這個示例中,renderer(_:didAdd:for:)方法調用了setupFaceNodeContent方法來向faceNode添加SceneKit內容。舉個??,如果你要改變demo中的showsCoordinateOrigin變量,demo app就會在這個節點(faceNode?)上添加一個虛擬x/y/z軸,指示臉部錨點的原點和坐標系。

使用臉部幾何來給用戶臉部建模

ARKit提供了契合用戶臉部尺寸、形狀、拓撲結構(面貌結構)和當前面部表情的粗略3D網格(學過ABAQUS的可能比較容易理解)。ARKit中提供ARSCNFaceGeometry類,能讓你輕易在SceneKit中把網格可視化。

你的AR體驗可以使用這個網格來放置或者渲染一些看上去貼在臉上的內容。比如你可以通過在這個幾何網格上添加一些半透明的紋理來在用戶皮膚上畫一個虛擬紋身或模擬化妝。

要創建一個SceneKit臉部幾何對象,用你SceneKit視圖使用的Metal device來初始化一個ARSCNFaceGeometry變量:

// This relies on the earlier check of `ARFaceTrackingConfiguration.isSupported`.
// 要前置判斷是否支持ARFaceTrackingConfiguration
let device = sceneView.device!
let maskGeometry = ARSCNFaceGeometry(device: device)!

這段示例代碼的setupFaceNodeContent方法(上文提到過)向scene添加了一個包含臉部幾何的node。通過使這個node成為臉部錨點的子node,臉部模型會自動追蹤用戶臉部的位置和旋轉。
要在用戶眨眼、說話或做不同的表情時讓模型隨用戶臉型變化,你需要在renderer(_:didUpdate:for:)代理回調方法中取出更新的臉部網格。

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let faceAnchor = anchor as? ARFaceAnchor else { return }
    
    virtualFaceNode?.update(withFaceAnchor: faceAnchor)
}

然后在你需要匹配的scene中通過將新臉部網格傳入update(from:)方法來更新ARSCNFaceGeometry對象:

func update(withFaceAnchor anchor: ARFaceAnchor) {
    let faceGeometry = geometry as! ARSCNFaceGeometry
    faceGeometry.update(from: anchor.geometry)
}
IMG_5284.JPG

在用戶的臉上放置3D內容

ARKit提供的另一個臉部網格的應用是:在你的scene中創建一個遮擋幾何體。遮擋幾何體是指一個不渲染任何可見內容,允許相機圖像(實際物體)穿越展示,但可以遮擋scene中其他的虛擬內容的3D模型。

這項技術實現了虛擬物體與真實面部相互作用的假象,即使臉是2D的相機圖像而虛擬內容是個3D的渲染物體。舉個栗子,如果你放置一個遮擋幾何體和一個虛擬眼鏡在用戶臉上,臉部可以擋住鏡框。

要在臉上創建一個遮擋幾何體,首先要創建一個ARSCNFaceGeometry對象geometry,就像上一個例子一樣。不同之處是上一個例子是用一個可見物體配置SceneKit的材質,這次要將材質設置為在渲染時使用深度而非顏色來渲染:

geometry.firstMaterial!.colorBufferWriteMask = []
occlusionNode = SCNNode(geometry: geometry)
occlusionNode.renderingOrder = -1

由于材料渲染的是深度,SceneKit渲染的其他物體會正確的顯示在它的前面或者后面。但因為材料并不渲染顏色,相機圖像會在它所在的位置出現。示例app用一個在用戶眼前的SceneKit物體(一個超大的AR文字),結合這個技術創建了一個逼真的“AR”被用戶鼻子遮擋的效果。

IMG_5283.JPG

讓一個復合形狀的角色活起來

除了上述兩個對于臉部網格的應用之外,ARKit還以blendShapes字典的方式提供一個更抽象的用戶臉部表情模型。你可以使用這個字典給出的系數值來控制你自己的2D或者3D模型的動畫參數,創建一個跟隨用戶實際臉部活動和表情的對象(比如一個狗狗頭像)。

作為一個復合形狀動畫的基本范本,這個示例包含了一個簡易的機器人形象??模型,這個模型是使用SceneKit原生形狀創建的(參考源碼中的robotHead.scn文件)。

要獲取用戶當前的面部表情,請查閱blendShapes字典,這個字典從代理回調renderer(_:didUpdate:for:)的面部錨點中取得:

func update(withFaceAnchor faceAnchor: ARFaceAnchor) {
    blendShapes = faceAnchor.blendShapes
}

然后,檢查這個字典的鍵值對來計算你的模型的動畫參數。總共有52個獨立的ARFaceAnchor.BlendShapeLocation系數。你的app可以使用必要的參數來創建你腦海中的藝術化效果。在這個示例中,RobotHead類做了相關的計算,將eyeBlinkLefteyeBlinkRight映射到機器人眼睛一個軸的scale值;把jawOpen映射到機器人的下巴位置的偏移距離。

var blendShapes: [ARFaceAnchor.BlendShapeLocation: Any] = [:] {
    didSet {
        guard let eyeBlinkLeft = blendShapes[.eyeBlinkLeft] as? Float,
            let eyeBlinkRight = blendShapes[.eyeBlinkRight] as? Float,
            let jawOpen = blendShapes[.jawOpen] as? Float
            else { return }
        eyeLeftNode.scale.z = 1 - eyeBlinkLeft
        eyeRightNode.scale.z = 1 - eyeBlinkRight
        jawNode.position.y = originalJawY - jawHeight * jawOpen
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容