ARKit 和 RealityKit 的 focal length
参数值是相同的。这是因为这两个框架被设计成可以一起使用。虽然目前 ARView
没有 focal length
实例属性,但是你可以轻松地在控制台中输出 ARSCNView 或者 SCNView
的 focal length
。
@IBOutlet var sceneView: ARSCNView!
sceneView.pointOfView?.camera?.focalLength
请注意,ARKit、RealityKit和SceneKit框架不使用屏幕分辨率,而是使用视口大小。iPhone视口的放大因子通常为1/2
或1/3
。
内在相机矩阵
正如你所说,在ARKit中存在一个3x3相机矩阵,允许您在2D相机平面和3D世界坐标空间之间进行转换。
var intrinsics: simd_float3x3 { get }
使用此矩阵,您可以打印出4个重要参数:fx
、fy
、ox
和oy
。让我们将它们全部打印出来:
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
print(" Focal Length: \(self.sceneView.pointOfView?.camera?.focalLength)")
print("Sensor Height: \(self.sceneView.pointOfView?.camera?.sensorHeight)")
let frame = self.sceneView.session.currentFrame
print("Intrinsics fx: \(frame?.camera.intrinsics.columns.0.x)")
print("Intrinsics fy: \(frame?.camera.intrinsics.columns.1.y)")
print("Intrinsics ox: \(frame?.camera.intrinsics.columns.2.x)")
print("Intrinsics oy: \(frame?.camera.intrinsics.columns.2.y)")
}
对于 iPhone X
,打印以下数值:
当你应用公式时,你会得到一个不可信的结果(继续阅读以了解原因)。
关于广角镜头和光学防抖技术
iPhone X 有两个后置摄像头传感器,这两个模块都配备了 光学图像稳定器 (OIS)。广角镜头提供 28 毫米的焦距 和光圈为 f / 1.8
,而长焦镜头则是 56 毫米和 f / 2.4
。
ARKit 和 RealityKit 使用广角镜头后置模块,在 iPhone X 的情况下,它是一枚 28mm 镜头。但是印刷出来的值 focal length = 20.78 mm
怎么样呢?我相信 28 mm
和 20.78 mm
之间的差异是由于视频稳定化占用了约 25% 的总图像区域。这是为了最终获得焦距值 28 mm
的图像。
红色边框是稳定阶段的裁剪边距。
结论
这是我的个人结论。我没有找到任何关于这个主题的参考资料,所以如果我的观点是错误的,请不要严格评判我(我承认可能有错误)。
我们都知道,随着焦距的增加,相机抖动会被放大。因此,焦距值越低,相机抖动越少。这对于 AR 应用程序中非抖动高质量的世界跟踪非常重要。此外,我坚信光学防抖技术在焦距值较低时效果更好。因此,在获取更宽的图像区域的同时,ARKit 工程师选择了较低的 focal length
值,然后经过稳定化后,我们得到了一个修改版本的图像,就像它具有 focal length = 28mm
一样。
因此,在我看来,计算 RealityKit 和 ARKit 的真实 focal length
没有意义,因为苹果工程师已经实现了一个“虚假”的 focal length
,以获得稳健的 AR 体验。