如何将相机外参矩阵转换为SCNCamera的位置和旋转

3

我正在尝试使用SceneKit实现增强现实技术。

我使用ARuco(OpenCV增强现实库)估算标记的位姿,并得到了内部相机矩阵和外部矩阵。

然后我使用内部矩阵的参数(fovy,aspect,zNear,zFar)配置了SCNCameraprojectionTransform

在OpenGL中,通常使用ModelView来计算相对于相机坐标的世界坐标,但是在SceneKit中,没有这样的ModelView。

因此,我计算了外部矩阵的逆矩阵以获取相机坐标相对于世界坐标(即标记坐标)的值。

我认为,通过包含旋转和平移矩阵的逆矩阵,我已经获得了正确的相机位置。

但是,我无法从中获取相机的旋转信息。

你有什么想法吗?

2个回答

8

SceneKit具有与OpenGL中相同的视图矩阵,只是在你开始操作着色器之前它们有些隐藏。我认为这有点过于隐蔽了。

你似乎已经理解了大部分内容。投影矩阵来自于你的相机projectionTransform,而视图矩阵来自于相机矩阵的反转SCNMatrix4Invert(cameraNode.transform)。在我的情况下,一切都是世界坐标,使我的模型矩阵变成了一个简单的单位矩阵。

我最终使用的代码来获取经典的模型-视图-投影矩阵类似于...

let projection = camera.projectionTransform()
let view = SCNMatrix4Invert(cameraNode.transform)
let model = SCNMatrix4Identity

let viewProjection = SCNMatrix4Mult(view, projection)
let modelViewProjection = SCNMatrix4Mult(model, viewProjection)

由于某些原因,我发现SCNMatrix4Mult(...)所需的参数顺序与我预期的不同(例如;与GLKMatrix4Multiply(...)相反)。

我仍然不完全明白这一点,因此欢迎进行编辑/提示。使用此方法,我无法使SceneKit MVP矩阵(传递给着色器)与上面代码计算出的矩阵匹配...但对于我所需的内容来说足够接近了。


我之前没有意识到我所需要的只是反转外部矩阵并将其设置为“SCNCamera”的“transform”!你的回答给了我一个提示。但我需要旋转外部矩阵,可能是因为OpenCV和OpenGL坐标系的差异。即使如此,我的3D模型仍然不能完全匹配真实标记。也许是内部参数的问题... - akira108
很高兴能够帮上一点忙。我以前从未接触过AR相关的东西,希望其他人能够帮助你。 - lock
@akira108,你能展示一下设置相机和模型变换的相关代码吗? - Cameron Lowell Palmer
@Cameron Lowell Palmer,我已经成功使用Vuforia框架计算的内在和外在矩阵设置了变换和投影变换。如果您感兴趣的话,我写了一篇关于此的文章,请看这里:http://qiita.com/akira108/items/a743138fca532ee193fe - akira108
@akira108 我也解决了。https://dev59.com/ipffa4cB1Zd3GeqP7WUb - Cameron Lowell Palmer

2
@lock的回答看起来不错,但需要增加一些内容:
(1)如果相机节点被动画或有父级,则访问SCNNode worldTransform而不是transform:
let view = SCNMatrix4Invert(cameraNode.presentationNode.worldTransform)

(2) 代码没有考虑视图的纵横比。例如,假设使用透视投影,您需要执行以下操作:

perspMatrix.m11 /= viewportAR; //if using Yfov -> adjust Y`
/* or, */
perspMatrix.m22 *= viewportAR; //if using Xfov -> adjust X`

其中,viewportAR = viewport.width / viewport.height

另一种方法是在场景中使用一个具有渲染委托的节点,并从该委托中检索SceneKit的矩阵(它们作为选项传递):

FOUNDATION_EXTERN NSString * const SCNModelTransform;
FOUNDATION_EXTERN NSString * const SCNViewTransform;
FOUNDATION_EXTERN NSString * const SCNProjectionTransform;
FOUNDATION_EXTERN NSString * const SCNNormalTransform;
FOUNDATION_EXTERN NSString * const SCNModelViewTransform;
FOUNDATION_EXTERN NSString * const SCNModelViewProjectionTransform;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接