如何从Vuforia GL矩阵计算相机位置?

2024-06-26

我计算了 a 的相机位置SCNScene这是在 Vuforia 中渲染的。然而,物体并没有固定在标记上,而是在移动时跳跃。场景中的立方体仅以正交方式出现,无论设备如何围绕侧面移动都无法看到。

相机位置是根据每一帧计算的:

// Get model view matrix
Vuforia::Matrix44F modelViewMatrix = Vuforia::Tool::convertPose2GLMatrix(result->getPose());

// Convert to extrinsic matrix
SCNMatrix4 extrinsic = [self SCNMatrix4FromVuforiaMatrix44: modelViewMatrix];
SCNMatrix4 inverted = SCNMatrix4Invert(extrinsic);

// Set new position of SCNCamera
cameraNode.transform = inverted;

当相机凝视时计算相机投影矩阵:

// Get device camera calibration    
const Vuforia::CameraCalibration& cameraCalibration = Vuforia::CameraDevice::getInstance().getCameraCalibration();
projectionGLMatrix = Vuforia::Tool::getProjectionGL(cameraCalibration, 2.0f, 5000.0f);

// Convert matrix
GLKMatrix4 glkMatrix;

for(int i=0; i<16; i++) {
    glkMatrix.m[i] = projectionGLMatrix.data[i];
}

// Convert matrix
SCNMatrix4 projectionTransform = SCNMatrix4FromGLKMatrix4(glkMatrix);
cameraNode.camera.projectionTransform = projectionTransform;

我在这里做错了什么?

Update 1

当相机启动时,投影矩阵现在计算如下:

const Vuforia::CameraCalibration& cameraCalibration = Vuforia::CameraDevice::getInstance().getCameraCalibration();
Vuforia::Matrix44F vuforiaMatrix = Vuforia::Tool::getProjectionGL(cameraCalibration, 2.0f, 5000.0f);
matrix_float4x4 simdMatrix = simdMatrixWithVuforiaMatrix44F(vuforiaMatrix);
cameraNode.camera.projectionTransform = SCNMatrix4FromMat4(simdMatrix);

相机位置随每一帧更新:

Vuforia::Matrix44F modelViewMatrix = Vuforia::Tool::convertPose2GLMatrix(result->getPose());
matrix_float4x4 simdMatrix = simdMatrixWithVuforiaMatrix44F(modelViewMatrix);
cameraNode.transform = SCNMatrix4FromMat4(simdMatrix);

NSLog(@"camera position: x%lf, y%lf, z%lf, rotation: x%lf, y%lf, z%lf", _cameraNode.position.x, _cameraNode.position.y, _cameraNode.position.z, _cameraNode.rotation.x, _cameraNode.rotation.y, _cameraNode.rotation.z);

By moving the device and observing the logging of the camera position (left graph) and rotation (right graph) it seems that the axes are: enter image description here

旋转轴与位置轴不同。此外,围绕剩余轴(下图中无标题)的旋转不会对在 0.999 左右浮动的cameraNode.rotation.x 值产生任何影响。

这里有什么问题吗?


你正在经历经典的“我在矩阵上做错了什么”行为,需要大量的反复试验才能解决。我还认为您一直在 Vuforia 网站上阅读内容,但这些内容几乎没有任何帮助。 :)

重新排列矩阵可能是你出错的地方。这SCNMatrix应该直接与OpenGL兼容。我实际上把一切都投入了simd::matrix4x4并使用内置的SCNMatrix4FromMat4将它们转换为SCNMatrix.

SceneKit 使用矩阵来表示坐标空间变换, 反过来又可以表示组合位置、旋转或 三维空间中物体的方向和比例。 SceneKit 矩阵结构按行优先顺序排列,因此它们是 适合传递给着色器程序或接受的 OpenGL API 矩阵参数。

所以,总结一下......我相信你应该删除:

SCNMatrix4 inverted = SCNMatrix4Invert(extrinsic);

至于复制GLMatrix to an SCNMatrix,无需尝试,应该是正确的。将使用您的方法生成的投影矩阵的结果与我的方法进行比较。它们应该是相同的。

投影矩阵

我得到这样的投影矩阵:

const Vuforia::Matrix44F projectionMatrix = Vuforia::Tool::getProjectionGL(cameraCalibration, nearPlane, farPlane);
simdMatrixWithVuforiaMatrix44F(projectionMatrix);

我将矩阵转换为simd::matrix4x4(我在 C++ 领域花费了大量时间)这只是 SceneKit 支持的 Apple 定义的结构。

#include <simd/simd.h>

matrix_float4x4 simdMatrixWithVuforiaMatrix44F(const Vuforia::Matrix44F &matrix)
{
    vector_float4 col0 = { matrix.data[0], matrix.data[1], matrix.data[2], matrix.data[3] };
    vector_float4 col1 = { matrix.data[4], matrix.data[5], matrix.data[6], matrix.data[7] };
    vector_float4 col2 = { matrix.data[8], matrix.data[9], matrix.data[10], matrix.data[11] };
    vector_float4 col3 = { matrix.data[12], matrix.data[13], matrix.data[14], matrix.data[15] };

    return matrix_from_columns(col0, col1, col2, col3);
}

返回视图控制器

let extrinsic = SCNMatrix4FromMat4(projectionMatrix)
_cameraNode?.camera?.projectionTransform = extrinsic

帧标记姿势

我有一个名为 Framemarker 的对象,它实际上包含标识符和姿势,但该姿势是相同的simd::matrix4x4作为投影矩阵。

for framemarker in framemarkers {
        switch framemarker.identifier {
        case 337:
            let pose = SCNMatrix4FromMat4(framemarker.pose)
            _firstNode?.transform = pose
            break
        case 357:
            let pose = SCNMatrix4FromMat4(framemarker.pose)
            _secondNode?.transform = pose
            break
        default:
            break
        }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从Vuforia GL矩阵计算相机位置? 的相关文章

  • 通过 NSDate 过滤 Realm 中的查询会抛出 NSInvalidArgumentException

    我到处寻找 甚至访问了一些带有永远不会消失的病毒警告消息的可疑网站 但我无法弄清楚这一点 我只是想过滤Results
  • Swift 和 Objective-C 框架公开其内部结构

    我正在尝试将 Swift 添加到具有公共 私有和项目文件的现有 Objective C 框架中 为了让 Swift 能够访问项目文件 我添加了一个定义新模块的模块映射 例如MyFramework Internal 通过包含所有项目标题 如下
  • 快速将数据从 tableviewcontroller 传递到另一个 tableviewcontroller

    我有一个正在创建的表单 该表单填充有用户输入的文本字段 回答完所有问题后 会弹出一个保存按钮 我在使此表视图控制器将数据传递到新的表视图控制器时遇到问题 我被困住了 不知道该怎么做 import UIKit class TableViewC
  • 如何在 SKAction 中途反转精灵所遵循的路径方向?

    我有一个 SKSpriteNode 它使用 SKAction 沿着圆形路径移动 create the path our sprite will travel along let circlePath CGPathCreateWithElli
  • 为什么快速枚举中的可选项会导致无限循环?

    评估以下代码 我希望打印一次Hello World 相反 它会导致无限循环 有人可以解释为什么吗 let array what for text String in array print Hello World 删除可选的 显然让它只打印
  • 连接到 Apple Music

    所以我尝试使用 React Native 应用程序从 iOS 设备连接到 Apple Music 有一个 API 可以执行相同的操作 但我需要从 storekit 框架调用一个函数 提出个性化请求 苹果音乐API https develop
  • 使用 NSOutlineView 作为文件系统目录浏览器的 Swift 代码

    我已经在这段 Swift 代码上苦苦挣扎了一段时间 但没有发现问题 代码 下面应该提供文件目录作为 NSOutlineView 的数据源 GUI 非常简单 只是一个带有 NSOutlineView 和 OutlineViewControll
  • 您可以严格泛型类型或为一个参数指定多个类型吗?

    例如我想指定一个类型可能是Integer or String并将其用作特殊类型func我试过typealias但它不会解决这个问题 因为类型别名不能有or参数作为其唯一用途 因此请考虑下面的情况 typealias alis StringP
  • Swift 制作按钮超链接

    我使用的是 swift 因为它是一种相当新的编程语言 所以没有太多关于它的文档 我正在尝试使按钮充当超链接 我已经创建了一个 IBAction 但我不知道从哪里开始 这是我的代码 import UIKit class ViewControl
  • 创建初始值为 0 的信号量会导致执行问题

    我正在学习 GCD 并有关于信号量的问题 这是我的代码 class ViewController UIViewController var semaphore dispatch semaphore t nil override func v
  • imageAvailableCallback 在基本 GPUImage2 相机设置中从未调用

    我已按照 GPUImage2 的 github 上的基本设置说明进行操作过滤直播视频 https github com BradLarson GPUImage2 filtering live video and 从视频中捕获图像 https
  • Swift 中可选的闭包属性

    如何在 Swift 中将可选闭包声明为属性 我正在使用这段代码 var respondToButton sender UIButton gt Bool 但编译器抱怨该属性未在初始化程序结束时初始化 我相信我可以通过将 var 声明为可选来解
  • ios 8 相机显示黑屏

    此代码用于从相机中一张一张地捕获图像 但在下次拍摄一张图像后 相机将打开但黑屏 就像它 快门关闭 所有其他 ios 版本都可以工作 但不能在 ios 8 中工作 请告诉我该如何解决呢 void openCamera if PickerHan
  • 解析 URL 字符串以获取键值的最佳方法?

    我需要解析一个 URL 字符串 如下所示 ad eurl http www youtube com video 4bL4FI1Gz6s hl it IT iv logging level 3 ad flags 0 endscreen mod
  • 格式化浮点值,保留 2 位小数[重复]

    这个问题在这里已经有答案了 如何将结果四舍五入到小数点后两位并将其显示在结果标签上 我发现了一些陈述 但我对 Swift 很陌生 实际上我很难为我的项目重建示例 import UIKit class ViewController UIVie
  • 如何对 SwiftyJSON JSON 对象进行子集化

    我正在构建一个 iOS 应用程序 其中我的一个 API 调用返回一个大型 JSON blob 我使用 SwiftyJSON 将其加载到 JSON 对象中 例如 它看起来像这样 data name object name id 1 descr
  • 为什么是!在 Swift 中称为“隐式”而不是“显式”解包可选?

    的名称 总是让我感到困惑 它被称为 隐式展开的可选 然而 其中隐含着什么呢 隐含的意思是 暗示但没有明确表达 但是 不添加 明确表达其目的 不添加一个 明确我们要实现的目标 在 Swift 中 尾随感叹号 有两种不同的使用方式 一种叫做强制
  • ios - 安排无限数量的本地通知

    我有一个应用程序 允许用户创建重复事件 每一个事件在一天中的特定时间可能有也可能没有提醒 警报 如果有的话 应用程序会发送一个本地通知在一天中的那个时候 事件存储在CoreData Event name Go to London date
  • 在 swift 中实现自定义markerInfoWindow不起作用

    我一直在使用下面发布的方法来显示自定义信息窗口 但是每当我运行它时 只显示默认窗口 带有标题 片段 我已经为以下方法创建了 xib 和 swift 文件 并且我尝试使用标准函数表示法 即 mapView mapView markerInfo
  • 如何在 Swift Playground 中将文本转换为 OSX 语音

    我正在尝试学习如何为 OSX 进行文本转语音 notiOS 在 Swift 中 我有一个带有代码的游乐场 import Cocoa let synth NSSpeechSynthesizer synth startSpeaking Hell

随机推荐