【问题标题】:How to convert camera extrinsic matrix to SCNCamera position and rotation如何将相机外在矩阵转换为 SCNCamera 位置和旋转
【发布时间】:2016-10-07 02:04:14
【问题描述】:

我正在尝试通过SceneKit 实现增强现实。

我通过使用 ARuco(OpenCV 增强现实库)估计标记的姿势得到了一个内在的相机矩阵和一个外在的矩阵。

我用内在矩阵的参数(fovy、aspect、zNear、zFar)设置了SCNCameraprojectionTransform

通常在OpenGL中,相对于相机坐标的世界坐标是用ModelView计算的,但在SceneKit中,没有modelView之类的东西。

所以我计算了外在矩阵的逆矩阵以获得相机相对于世界坐标的坐标(标记坐标)。

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

但是我无法从中获得相机的旋转

你有什么想法吗?

【问题讨论】:

    标签: ios opengl-es augmented-reality scenekit aruco


    【解决方案1】:

    SceneKit 具有与您在 OpenGL 中遇到的相同的视图矩阵,它们只是稍微隐藏了一点,直到您开始使用着色器。 IMO 有点太隐蔽了。

    您似乎已经解决了大部分问题。投影矩阵来自你的相机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(...) 相反)。

    我仍然不是 100% 的,所以欢迎编辑/提示。使用这种方法,我无法让 SceneKit MVP 矩阵(传递给着色器)与上面代码计算的矩阵相匹配......但它已经足够接近我需要的了。

    【讨论】:

    • 我还没有意识到我需要的只是反转外在矩阵并将其设置为SCNCameras transform!你的回答给了我一个提示。但是我需要旋转外在矩阵可能是因为OpenCV的坐标和OpenGL的坐标不同。仍然我的 3D 模型看起来与真实标记不完全匹配。也许是内在参数问题......
    • 很高兴它有点帮助。以前从未看过 AR 的东西,希望其他人可以帮助你。
    • @akira108 你能显示设置相机和模型变换的相关代码吗?
    • @Cameron Lowell Palmer 我已经成功地使用 Vuforia 框架计算的内在和外在矩阵设置了变换和投影变换。我写了一篇关于这个的文章,如果你有兴趣,请看一下:)qiita.com/akira108/items/a743138fca532ee193fe
    • @akira108 我也解决了。 stackoverflow.com/questions/37434816/…
    【解决方案2】:

    @lock 的答案看起来不错,有几个补充:

    (1) 访问 SCNNode worldTransform 而不是 transform 如果 cameraNode 是动画或父节点:

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      • 2017-10-14
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 2010-12-06
      相关资源
      最近更新 更多