[ARKit]8-對裸眼3D效果一次不太成功的嘗試

說明

ARKit系列文章目錄git

The Parallax View

The Parallax View是個國外開發者開發的好玩的軟件,它利用iPhoneX實現了裸眼3D的效果. github

其實它是利用了iPhone X的ARKit面部追蹤接口和TrueDepth傳感器。
經過追蹤用戶的頭部運動,肯定眼睛在三維空間中的確切位置。
而後生成實時響應用戶位置的影像,從而爲用戶帶來一種3D影像的錯覺。

原理特色

經過使用ARKit和iPhone X進行3D頭部追蹤來得到深度幻象。swift

爲得到最佳效果,應該只打開一隻眼睛(該應用容許選擇要追蹤的眼睛,或者能夠嘗試自動選擇眼睛)session

經過跟蹤用戶頭部方向和位置,能夠找到3D中的眼睛位置。app

應用能夠在該顯示器上呈現從該位置看到的正確視圖。框架

爲了呈現該視圖,使用離軸投影(非對稱相機平截頭體)。編輯器

這給人一種錯覺,即物體出如今屏幕的前面和後面。post

模仿

受此啓發,我嘗試在非iPhoneX設備上用人臉識別框架來實現低精度的裸眼3D效果. 原理是:測試

  • 利用人臉識別,檢測人臉位置;
  • 將人臉的二維位置轉換到3維空間中(z軸固定,xy按比例轉換);
  • 將轉換後的3D座標賦值給攝像機;

本來打算,用識別出人臉的大小,作爲依據來判斷攝像機在z軸上的位置,但測試中發現,人臉識別出的大小變化很大,無規律可轉換.ui

創建模型

本身用SceneKit的編輯器搭建了一個場景,裏面有多根高度不一樣的柱子.

人臉識別

原來覺得蘋果的新框架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

相關文章
相關標籤/搜索