ARKit系列文章目錄git
The Parallax View是個國外開發者開發的好玩的軟件,它利用iPhoneX實現了裸眼3D的效果. github
其實它是利用了iPhone X的ARKit面部追蹤接口和TrueDepth傳感器。 經過追蹤用戶的頭部運動,肯定眼睛在三維空間中的確切位置。 而後生成實時響應用戶位置的影像,從而爲用戶帶來一種3D影像的錯覺。經過使用ARKit和iPhone X進行3D頭部追蹤來得到深度幻象。swift
爲得到最佳效果,應該只打開一隻眼睛(該應用容許選擇要追蹤的眼睛,或者能夠嘗試自動選擇眼睛)session
經過跟蹤用戶頭部方向和位置,能夠找到3D中的眼睛位置。app
應用能夠在該顯示器上呈現從該位置看到的正確視圖。框架
爲了呈現該視圖,使用離軸投影(非對稱相機平截頭體)。編輯器
這給人一種錯覺,即物體出如今屏幕的前面和後面。post
受此啓發,我嘗試在非iPhoneX設備上用人臉識別框架來實現低精度的裸眼3D效果. 原理是:測試
本來打算,用識別出人臉的大小,作爲依據來判斷攝像機在z軸上的位置,但測試中發現,人臉識別出的大小變化很大,無規律可轉換.ui
原來覺得蘋果的新框架Vision會更好,結果在個人iPhone SE上很是卡,並且Vision框架在識別人臉時對方向有要求,須要指定方向.全部最後仍是使用了AVFoundation中的metadataObjectTypes來識別.
if session.canAddOutput(metaDataOutput) {
session.addOutput(metaDataOutput)
}
//7.AVFoundation框架識別類型
metaDataOutput.metadataObjectTypes = [.face]
複製代碼
在代理方法中處理識別到的人臉:
//AV框架人臉識別
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
for obj in metadataObjects {
if obj.type == .face {
print("face---\(obj.bounds)")
// 座標轉換
let oldRect = obj.bounds;
let w = oldRect.size.height * self.previewView.bounds.size.width;
let h = oldRect.size.width * self.previewView.bounds.size.height;
let x = oldRect.origin.y * self.previewView.bounds.size.width;
let y = oldRect.origin.x * self.previewView.bounds.size.height;
// 添加矩形
rectLayer.frame = CGRect(x: x, y: y, width: w, height: h)
rectLayer.isHidden = false
//湊出合理的數據
let cameraX = (oldRect.origin.y - 0.3) * 2
let cameraY = (0.4 - oldRect.origin.x) * 2
// 移動攝像機
self.cameraNode.position = SCNVector3(cameraX, cameraY, 20)
}else {
rectLayer.isHidden = true
}
}
}
複製代碼
效果初步有了:
可是咱們還應該看到,咱們的3D效果是經過直接移動攝像機的位置來實現,攝像機的視野範圍並無改變,因此看上去像是透過窗戶看後面的景物,而不是像The Parallax View那樣,3D物體像是與手機屏幕綁在一塊兒.
最主要緣由是:The Parallax View使用了離軸投影(非對稱相機平截頭體)處理攝像機看到的物體範圍,以下圖,不論如何移動,FOV(Field Of View)都始終對齊了底座的四個角:
在SceneKit中,是能夠給camera設置自定義的投影變換矩陣的 self.cameraNode.camera?.projectionTransform
蘋果也給出了說明,一旦設置該項,則對攝像機設置的 zFar
,zNear
, 和fieldOfView
都會失效,緣由是這些值沒法從矩陣中獲得(數學上不可逆). 另外須要注意的是:ARKit中的ARSCNView類會重寫這個投影變換,因此不要在AR應用中修改.
若是有深厚的3D數學功底,只要重寫這個投影變換矩陣,就能夠獲得離軸投影效果,惋惜我如今不會,相關配置還須要研究,之後更新.
代碼地址NakedEye3D