当前位置首页 > 信息公告

[AR/MR基础]借助iPhoneX的深度单反(TruthDepth

更新时间:2023-10-31 文章作者:佚名 信息来源:网络整理 阅读次数:

近来在做三维姿态恐怕的东西,用到了上的深度摄像头(),我们都晓得深度摄像头可以获得某个点的三维信息(基于此可以做好多有趣的东西,例如三维重建,三维关键点跟踪与检查,后续有空渐渐填坑),但具体怎么获得网上能找到的资料也不多,我在这儿整理了一下我近来收集到的资料并提供了基于Swift的示例代码,该文章分成下边几小节来探讨。Yjy物理好资源网(原物理ok网)

虽然最后估算获得三维座标系的方式很简单凸透镜成像原理应用,但要了解为何要这样估算须要清楚单反成像的原理。Yjy物理好资源网(原物理ok网)

单反大致工作原理Yjy物理好资源网(原物理ok网)

X采用的是结构光的方案,这儿以的工作流程来解释下它是怎样获取深度值的:Yjy物理好资源网(原物理ok网)

点阵投影器和泛光照明器都可以投射红外线光点,不同之处在于后者帧率高前者帧率低,且后者投射结构光,前者投射非结构光。Yjy物理好资源网(原物理ok网)

这儿并不对原理展开讲,感盛行的可以移步阅读尾部的参考链接Yjy物理好资源网(原物理ok网)

凸透镜成像中的焦距和光心Yjy物理好资源网(原物理ok网)

不同角度出发的光线经过透镜,跟透镜表面产生不同的倾角,形成不同程度的折射。Yjy物理好资源网(原物理ok网)

从一个真实世界w的一点出发的光,经过透镜,又重新汇集到一点,最终产生了点对点的成像关系,从上图我们可以得出以下几个名词的定义。Yjy物理好资源网(原物理ok网)

光心:凸透镜的中心Yjy物理好资源网(原物理ok网)

焦点:一束光以凸透镜的主轴穿过凸透镜时,在凸透镜的另外两侧会被凸透镜凝聚成一点,这一点称作焦点。Yjy物理好资源网(原物理ok网)

焦距:焦点到凸透镜光心的距离就称作这个凸透镜的焦距,一个凸透镜的一侧各自有一个焦点。Yjy物理好资源网(原物理ok网)

清楚这几个基本概念后理解下边几个座标系就愈加容易了。Yjy物理好资源网(原物理ok网)

单反成像中所用到的世界,单反凸透镜成像原理应用,图象,象素座标系Yjy物理好资源网(原物理ok网)

我们换一张成像的原理图Yjy物理好资源网(原物理ok网)

成像过程中须要经过几个座标系的转换,最后显示在我们的屏幕上。Yjy物理好资源网(原物理ok网)

通常来说,须要经过四个座标系的转换。Yjy物理好资源网(原物理ok网)

世界座标系Yjy物理好资源网(原物理ok网)

描述现实世界中物体所处的三维座标。Yjy物理好资源网(原物理ok网)

单反座标系Yjy物理好资源网(原物理ok网)

以单反的光心为座标原点,x轴和y轴分别平行于图象座标系的x轴和y轴,单反的光轴为z轴。Yjy物理好资源网(原物理ok网)

图象座标系Yjy物理好资源网(原物理ok网)

以图象平面(通常指传感)的中心为座标原点,x轴和y轴分别平行于图象平面的两条垂直边,用(x,y)表示其座标值,图象座标系是用化学单位(比如毫米)表示象素在图象中的位置。Yjy物理好资源网(原物理ok网)

象素座标系Yjy物理好资源网(原物理ok网)

以图象平面左上角的顶点为原点,x轴和y轴分别平行于图象坐标的x轴和y轴,用(u,v)表示其座标值。这个座标系也就是最终在我们手机上显示的座标系。Yjy物理好资源网(原物理ok网)

所以,假若我们假如我们想获得象素点对应的三维坐标的话,就要按照象素座标系反推回单反座标系中。而怎样反推就涉及到几个座标系之间的转换方式。Yjy物理好资源网(原物理ok网)

已知一个现实世界中的物体点在世界座标系中的座标为(X,Y,Z),单反座标系为(Xc,Yc,Zc),图象座标系中的座标为(x,y),象素座标系上的座标为(u,v)Yjy物理好资源网(原物理ok网)

象素座标系与图象座标系之间的转换为:Yjy物理好资源网(原物理ok网)

其中u0,v0是图象座标系原点在象素座标系中的座标,dx和dy分别是每位象素在图象平面上x和y方向上的规格,这种值也被称为图象的内参矩阵,是可以通过API领到的。Yjy物理好资源网(原物理ok网)

图象座标系与单反座标系之间的转换为:Yjy物理好资源网(原物理ok网)

其中f为焦距,为何如此转换是按照相像三角形定律得到的,如右图所示:Yjy物理好资源网(原物理ok网)

最后则是单反座标系与世界座标系的转换关系:Yjy物理好资源网(原物理ok网)

其中R为3x3的正交旋转矩阵,t为三维平移向量,这几个参数也被称为单反的外参矩阵,也是可以领到的。Yjy物理好资源网(原物理ok网)

在通常的应用中,我们只须要从象素座标系转换到单反座标系就够用了。Yjy物理好资源网(原物理ok网)

基本知识都打算完毕,接下来看怎样在上获取象素点的三维座标。Yjy物理好资源网(原物理ok网)

在Swift按照象素点估算出它基于单反的三维座标Yjy物理好资源网(原物理ok网)

在Swift中启动单反主要有以下三个步骤Yjy物理好资源网(原物理ok网)

// 1. 发现 TruthDepth 相机
let videoDeviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInTrueDepthCamera], mediaType: .video, position: .front)
// 2. 初始化输入和输出
let videoDeviceInput = try AVCaptureDeviceInput(device: videoDeviceDiscoverySession.devices.first!)
// 3. 给 session 添加输出
let depthDataOutput = AVCaptureDepthDataOutput() session.addOutput(depthDataOutput) depthDataOutput.setDelegate(self, callbackQueue: dataOutputQueue)
Yjy物理好资源网(原物理ok网)

由于我们设置了,所以单反只要捕捉到一帧深度图都会反弹下边这个函数Yjy物理好资源网(原物理ok网)

func dataOutputSynchronizer(_ synchronizer: AVCaptureDataOutputSynchronizer, didOutput synchronizedDataCollection: AVCaptureSynchronizedDataCollection) {
        ...
        // 获得相机内参数和对应的分辨率
        let intrinsicMartix = syncedDepthData.depthData.cameraCalibrationData?.intrinsicMatrix
        let refenceDimension = syncedDepthData.depthData.cameraCalibrationData?.intrinsicMatrixReferenceDimensions
        self.camFx = intrinsicMartix![0][0]
        self.camFy = intrinsicMartix![1][1]
        self.camOx = intrinsicMartix![0][2]
        self.camOy = intrinsicMartix![1][2]
        self.refWidth = Float(refenceDimension!.width)
        self.refHeight = Float(refenceDimension!.height)
        ...
}
Yjy物理好资源网(原物理ok网)

在这个反弹函数里,我们可以获得摄像头的内参数,示例的程序中,只要触摸预览图中某一个象素点,程序会调用下边代码块输出该象素点在单反座标系下的X,Y和Z的值。Yjy物理好资源网(原物理ok网)

    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        let touchPoint = (touches as NSSet).allObjects[0] as! UITouch
        // 获得像素坐标系的坐标
        let coord = touchPoint.location(in: self.preview)
        let viewContent = self.preview.bounds
        let xRatio = Float(coord.x / viewContent.size.width)
        let yRatio = Float(coord.y / viewContent.size.height)
        // 获得触摸像素点的深度值 Z,单位为 cm
        let realZ = getDepth(from: depthPixelBuffer!, atXRatio: xRatio, atYRatio: yRatio)
        // 获得对应的 X 和 Y 值,计算公式其实就是两个坐标转换矩阵之间相乘后的结果
        // 像素 -> 图像 -> 相机坐标系
        let realX = (xRatio * refWidth! - camOx!) * realZ / camFx!
        let realY = (yRatio * refHeight! - camOy!) * realZ / camFy!
        DispatchQueue.main.async {
            self.touchCoord.text = String.localizedStringWithFormat("X = %.2f cm, Y = %.2f cm, Z = %.2f cm", realX, realY, realZ)
        }
    }
Yjy物理好资源网(原物理ok网)

示例程序的疗效图如下:Yjy物理好资源网(原物理ok网)

image.pngYjy物理好资源网(原物理ok网)

这儿输出的是黑色点对应的X,Y,Z值,完整代码戳这儿。Yjy物理好资源网(原物理ok网)

参考链接Yjy物理好资源网(原物理ok网)

[1]手臂辨识技术解析Yjy物理好资源网(原物理ok网)

[2]Quoar:WhatisthefloodinXfor?Yjy物理好资源网(原物理ok网)

[3]世界,单反,图象,象素座标系之间的关系Yjy物理好资源网(原物理ok网)

[4]Guide-AppleYjy物理好资源网(原物理ok网)

[5]PhotoandVideoUsingDepthYjy物理好资源网(原物理ok网)

发表评论

统计代码放这里