ARKit中的sceneView.pointOfView.transform和ARCamera.transform有什么区别?

问题描述

我对照相机的几何图形有一定的了解,但是我是Swift和ARKit开发的新手,在可以返回的不同类型的转换矩阵之间我有些困惑。

特别是,我遵循的一个教程中,我以sceneView的形式抓取ARSCNView,然后打印sceneView.pointOfView .transform。这向我展示了我的期望:当会话开始时,4x4矩阵非常接近身份。

但是,当使用与每个ARCamera相关联的ARFrame时,如以下代码片段所示:

extension ViewController: ARSessionDelegate {
    
    func session(_ session: ARSession,didUpdate frame: ARFrame) {
        print(frame.camera.transform.transpose)
    }
}

相反,我得到一个看起来像的相机矩阵(请注意,转置是有意的,因为我对行主要布局更加熟悉):

[0  1  0  0]
[-1 0  0  0]
[0  0  1  0]
[0  0  0  1]

我已经尝试将.gravity.gravityAndHeading的{​​{3}}属性明确地尝试过,但是在运行会话时,它们都不产生预期的身份矩阵。

我还添加了.showWorldOrigin调试选项,该选项可以按预期显示世界坐标轴:手机右侧为+ X,视图轴为+ Y,而视图轴为-Z。

我在这里想念什么?有人可以澄清一下ARFrame返回的变换的坐标系及其与ARSCNView的区别吗?

解决方法

唯一的区别是类型。身份矩阵在任何情况下都是相同的。

但是,旋转矩阵的倒数是其 @IBOutlet var arView: ARView! arView.cameraTransform.matrix.columns.3.x // camera position x arView.cameraTransform.matrix.columns.3.y // camera position y arView.cameraTransform.matrix.columns.3.z // camera position z // 0 1 2 3 indices ┌ ┐ | 1 0 0 x | | 0 1 0 y | | 0 0 1 z | | 0 0 0 1 | └ ┘


SCNMatrix4

extension ViewController: ARSessionDelegate {

    func session(_ session: ARSession,didUpdate frame: ARFrame) {
    
        frame.camera.transform.columns.3.x    // camera position x
        frame.camera.transform.columns.3.y    // camera position y
        frame.camera.transform.columns.3.z    // camera position z
    }
}

┌              ┐
|  1  0  0  x  |
|  0  1  0  y  |
|  0  0  1  z  |
|  0  0  0  1  |
└              ┘

float4x4 | simd_float4x4

frame.camera.transform

simd_float4x4

//   1st column     2nd column     3rd column     4th column
    ([1,0],[0,1,[x,y,z,1])

但是,如果您打印//Create a string to hold the file location string fileLocation; //Create an openfiledialog object to select a photo OpenFileDialog dialog = new OpenFileDialog { InitialDirectory = Directory.GetParent(Directory.GetParent (Environment.CurrentDirectory).ToString()).ToString(),Title = "Browse Images",CheckFileExists = true,CheckPathExists = true,FilterIndex = 2,RestoreDirectory = true,ReadOnlyChecked = true,ShowReadOnly = true }; if (dialog.ShowDialog() == true) { fileLocation = dialog.FileName; Mat input = CvInvoke.Imread(fileLocation,ImreadModes.AnyColor); } ,则会得到列的水平表示形式:

log4j.rootLogger = INFO,FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=/tmp/log.out
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...