ARKit框架詳細(xì)解析(五)—— 創(chuàng)建基于面部的AR體驗(yàn)

版本記錄

版本號 時(shí)間
V1.0 2017.09.27

前言

蘋果最近新出的一個(gè)API就是ARKit,是在2017年6月6日溶耘,蘋果發(fā)布iOS11系統(tǒng)所新增框架谐区,它能夠幫助我們以最簡單快捷的方式實(shí)現(xiàn)AR技術(shù)功能叉瘩。接下來幾篇我們就詳細(xì)的對ARKit框架進(jìn)行詳細(xì)的解析竟宋。AR相關(guān)代碼已經(jīng)上傳到Github - 刀客傳奇提完,感興趣的可以看上面幾篇。
1. ARKit框架詳細(xì)解析(一)—— 基本概覽
2. ARKit框架詳細(xì)解析(二)—— 關(guān)于增強(qiáng)現(xiàn)實(shí)和ARKit
3. ARKit框架詳細(xì)解析(三)—— 開啟你的第一個(gè)AR體驗(yàn)之旅
4. ARKit框架詳細(xì)解析(四)—— 處理增強(qiáng)現(xiàn)實(shí)中的3D交互和UI控件

創(chuàng)建基于面部的AR體驗(yàn)

放置和動(dòng)畫3D用戶臉部的內(nèi)容袜硫,并匹配面部表情(在具有兼容的前置攝像頭的設(shè)備上)氯葬。


概要

此示例應(yīng)用程序提供了一個(gè)簡單的界面挡篓,允許您使用兼容設(shè)備上的前置攝像頭在四個(gè)增強(qiáng)現(xiàn)實(shí)(AR)可視化之間進(jìn)行選擇(請iOS Device Compatibility Reference)婉陷。

  • 單獨(dú)的相機(jī)視圖,沒有任何AR內(nèi)容官研。
  • ARKit提供的面部網(wǎng)格秽澳,可以自動(dòng)估計(jì)真實(shí)的定向照明環(huán)境。
  • 虛擬3D內(nèi)容似乎附加到用戶的真實(shí)面孔(并被部分遮蔽)戏羽。
  • 一個(gè)簡單的機(jī)器人角色担神,其表情符合用戶的動(dòng)畫。

使用示例應(yīng)用程序中的“+”按鈕在這些模式之間切換始花,如下所示妄讯。


Start a Face Tracking Session in a SceneKit View - 在SceneKit視圖中啟動(dòng)面部跟蹤會話

像ARKit的其他用途一樣,臉部跟蹤需要配置和運(yùn)行會話(ARSession對象)酷宵,并將視頻圖像與虛擬內(nèi)容一起渲染亥贸。 有關(guān)會話和視圖設(shè)置的更詳細(xì)說明,請參閱About Augmented Reality and ARKitBuilding Your First AR Experience浇垦。 此示例使用SceneKit顯示AR體驗(yàn)炕置,但也可以使用SpriteKit或使用Metal構(gòu)建您自己的渲染器(請參閱ARSKViewDisplaying an AR Experience with Metal)。

面部跟蹤與用于配置會話的類中的ARKit的其他用途不同男韧。 要啟用臉部跟蹤朴摊,請創(chuàng)建一個(gè)實(shí)例,配置其屬性此虑,并將其傳遞給與視圖關(guān)聯(lián)的AR會話的方法甚纲,如下所示。

guard ARFaceTrackingConfiguration.isSupported else { return }
let configuration = ARFaceTrackingConfiguration()
configuration.isLightEstimationEnabled = true
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])

在提供需要面部跟蹤AR會話的用戶功能之前朦前,請先檢查.屬性來確定當(dāng)前設(shè)備是否支持ARKit的臉部跟蹤介杆。


Track the Position and Orientation of a Face - 跟蹤面部的位置和方向

當(dāng)臉部跟蹤處于活動(dòng)狀態(tài)時(shí)讹弯,ARKit會自動(dòng)將對象添加到正在運(yùn)行的AR會話中,其中包含有關(guān)用戶臉部的信息这溅,包括其位置和方向组民。

注意:ARKit會檢測并提供有關(guān)用戶臉部信息的信息。 如果攝像機(jī)圖像中存在多個(gè)面部悲靴,則ARKit會選擇最大或最清晰可識別的臉部臭胜。

在基于SceneKit的AR體驗(yàn)中,您可以在方法(從協(xié)議)中添加與面錨相對應(yīng)的3D內(nèi)容癞尚。 ARKit為錨點(diǎn)添加了一個(gè)SceneKit節(jié)點(diǎn)耸三,并更新了每一幀上節(jié)點(diǎn)的位置和方向,因此您添加到該節(jié)點(diǎn)的任何SceneKit內(nèi)容都會自動(dòng)跟隨用戶臉部的位置和方向浇揩。

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 = node
    serialQueue.async {
        self.setupFaceNodeContent()
    }
}

在此示例中仪壮,該方法調(diào)用setupFaceNodeContent方法將SceneKit內(nèi)容添加到faceNode。 例如胳徽,如果您更改示例代碼中的showsCoordinateOrigin變量积锅,則應(yīng)用程序?qū) / y / z軸的可視化添加到該節(jié)點(diǎn),指示面部錨點(diǎn)坐標(biāo)系的起點(diǎn)养盗。


Use Face Geometry to Model the User’s Face - 使用面幾何來建模用戶臉部

ARKit提供與用戶臉部的大小缚陷,形狀,拓?fù)浜彤?dāng)前面部表情相匹配的粗略3D網(wǎng)格幾何往核。 ARKit還提供了該類箫爷,提供了一種在SceneKit中可視化此網(wǎng)格的簡單方法。

您的AR體驗(yàn)可以使用此網(wǎng)格放置或繪制似乎附加到臉部的內(nèi)容聂儒。 例如虎锚,通過將半透明紋理應(yīng)用于此幾何體,您可以將虛擬紋身或化妝畫到用戶的皮膚上衩婚。

要?jiǎng)?chuàng)建一個(gè)SceneKit面幾何窜护,使用SceneKit視圖用于呈現(xiàn)的Metal設(shè)備初始化一個(gè)對象:

// This relies on the earlier check of `ARFaceTrackingConfiguration.isSupported`.
let device = sceneView.device!
let maskGeometry = ARSCNFaceGeometry(device: device)!

示例代碼的setupFaceNodeContent方法(如上所述)將包含面幾何的節(jié)點(diǎn)添加到場景中。 通過使該節(jié)點(diǎn)成為由臉部錨點(diǎn)提供的節(jié)點(diǎn)的子節(jié)點(diǎn)谅猾,臉部模型自動(dòng)跟蹤用戶臉部的位置和方向柄慰。

為了使屏幕上的臉部模型符合用戶臉部的形狀,即使用戶眨眼税娜,說話并進(jìn)行各種面部表情坐搔,您需要在委托回調(diào)中檢索更新的臉部網(wǎng)格。

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

然后敬矩,通過將新的面網(wǎng)格傳遞給其方法來更新場景中的對象進(jìn)行匹配:

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

Place 3D Content on the User’s Face - 將3D內(nèi)容放在用戶臉上

ARKit提供的面部網(wǎng)格的另一個(gè)用途是在場景中創(chuàng)建遮擋幾何概行。 遮擋幾何是不會呈現(xiàn)任何可見內(nèi)容(允許相機(jī)圖像顯示)的3D模型,但會阻礙相機(jī)對場景中其他虛擬內(nèi)容的視圖弧岳。

這種技術(shù)創(chuàng)造出真實(shí)面對與虛擬對象交互的錯(cuò)覺凳忙,即使臉部是2D攝像機(jī)圖像业踏,虛擬內(nèi)容是渲染的3D對象。 例如涧卵,如果您將遮擋幾何圖形和虛擬眼鏡放置在用戶的臉部上勤家,則臉部可能會遮擋眼鏡框架。

要?jiǎng)?chuàng)建面部的遮擋幾何柳恐,請先創(chuàng)建一個(gè)對象伐脖,如上例所示。 但是乐设,不要使用可見的外觀來配置該對象的SceneKit材質(zhì)讼庇,而是在渲染期間將材質(zhì)設(shè)置為渲染深度而不是顏色:

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

因?yàn)椴牧箱秩旧疃龋許ceneKit渲染的其他對象正確地出現(xiàn)在它的前面或后面近尚。 但是由于材質(zhì)不會呈現(xiàn)顏色蠕啄,相機(jī)圖像會出現(xiàn)在其位置。 示例應(yīng)用程序?qū)⒋思夹g(shù)與位于用戶眼睛前方的SceneKit對象相結(jié)合戈锻,創(chuàng)建一個(gè)效果歼跟,其中對象被用戶的鼻子實(shí)際遮蔽。


Animate a Character with Blend Shapes - 用混合形狀動(dòng)畫化一個(gè)人物

除了上述示例中所示的面部網(wǎng)格之外舶沛,ARKit還提供了一種以詞典形式的用戶面部表情的更抽象的模型嘹承。 您可以使用該字典中的命名系數(shù)值來控制自己的2D或3D資產(chǎn)的動(dòng)畫參數(shù),創(chuàng)建遵循用戶真實(shí)面部動(dòng)作和表達(dá)的角色(如頭像或木偶)如庭。

作為混合形狀動(dòng)畫的基本演示,此示例包含使用SceneKit原始形狀創(chuàng)建的機(jī)器人角色頭部的簡單模型撼港。 (請參閱源代碼中的robotHead.scn文件坪它。)

要獲取用戶當(dāng)前的面部表情,請從代理回調(diào)中的面部錨點(diǎn)中讀取字典:

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

然后帝牡,檢查該字典中的鍵值對以計(jì)算模型的動(dòng)畫參數(shù)往毡。 有52個(gè)獨(dú)特系數(shù)。 您的應(yīng)用程序可以使用盡可能少的或很多的必要條件來創(chuàng)建您想要的藝術(shù)效果靶溜。 在該示例中开瞭,RobotHead類執(zhí)行此計(jì)算,將參數(shù)映射到機(jī)器人眼睛因子的一個(gè)軸罩息,以及偏移機(jī)器人下顎位置的參數(shù)嗤详。

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
    }
}

后記

未完,待續(xù)~~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瓷炮,一起剝皮案震驚了整個(gè)濱河市葱色,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娘香,老刑警劉巖苍狰,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件办龄,死亡現(xiàn)場離奇詭異,居然都是意外死亡淋昭,警方通過查閱死者的電腦和手機(jī)俐填,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翔忽,“玉大人玷禽,你說我怎么就攤上這事⊙酱颍” “怎么了矢赁?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贬丛。 經(jīng)常有香客問我撩银,道長,這世上最難降的妖魔是什么豺憔? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任额获,我火速辦了婚禮,結(jié)果婚禮上恭应,老公的妹妹穿的比我還像新娘抄邀。我一直安慰自己,他們只是感情好昼榛,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布境肾。 她就那樣靜靜地躺著,像睡著了一般胆屿。 火紅的嫁衣襯著肌膚如雪奥喻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天非迹,我揣著相機(jī)與錄音环鲤,去河邊找鬼。 笑死憎兽,一個(gè)胖子當(dāng)著我的面吹牛冷离,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纯命,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼西剥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了扎附?” 一聲冷哼從身側(cè)響起蔫耽,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后匙铡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體图甜,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年鳖眼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黑毅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钦讳,死狀恐怖矿瘦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愿卒,我是刑警寧澤缚去,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站琼开,受9級特大地震影響易结,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柜候,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一搞动、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渣刷,春花似錦鹦肿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至碌识,卻和暖如春碾篡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背筏餐。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牡拇,地道東北人魁瞪。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像惠呼,于是被迫代替她去往敵國和親导俘。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容