You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在iOS中从Vuforia返回的Pose获取目标的2D屏幕坐标

在iOS平台通过Vuforia Pose计算目标2D屏幕坐标

核心思路

无需深入矩阵数学,直接利用Vuforia提供的ModelViewProjection(MVP)矩阵,将目标的3D局部坐标转换为屏幕2D坐标,步骤分为:矩阵变换、透视除法、屏幕坐标映射。

实现代码

以下是Swift和Objective-C的可直接复用代码,需在Vuforia的追踪回调中执行:

Swift 版本

func didTrackablePoseUpdated(_ trackableResult: TrackableResult, state: TrackableBehaviour.Status) {
    guard state == .tracked else { return }
    
    // 1. 获取Vuforia返回的MVP矩阵并转为SIMD矩阵
    let mvpRawArray = trackableResult.pose.modelViewProjectionMatrix
    let mvpMatrix = float4x4(mvpRawArray)
    
    // 2. 定义目标的3D局部坐标(示例为目标中心,可替换为目标上任意点)
    let target3DPoint = SIMD3<Float>(0, 0, 0)
    
    // 3. 转为齐次坐标并执行矩阵变换
    let homogeneousPoint = SIMD4<Float>(target3DPoint.x, target3DPoint.y, target3DPoint.z, 1.0)
    let transformedPoint = mvpMatrix * homogeneousPoint
    
    // 4. 透视除法得到NDC空间坐标(范围[-1,1])
    let ndcX = transformedPoint.x / transformedPoint.w
    let ndcY = transformedPoint.y / transformedPoint.w
    
    // 5. 映射为iOS屏幕坐标(左上角为原点)
    let screenBounds = UIScreen.main.bounds
    let screenX = (ndcX + 1.0) * screenBounds.width / 2.0
    let screenY = (1.0 - ndcY) * screenBounds.height / 2.0
    
    // 最终屏幕坐标可直接使用
    print("目标屏幕坐标:(\(screenX), \(screenY))")
}

Objective-C 版本

- (void)didTrackablePoseUpdated:(VuforiaTrackableResult *)trackableResult state:(VuforiaTrackableBehaviourStatus)state {
    if (state != VuforiaTrackableBehaviourStatusTracked) return;
    
    // 1. 获取MVP矩阵并构造4x4矩阵(列主序,匹配Vuforia返回格式)
    const float* mvpRawArray = trackableResult.pose.modelViewProjectionMatrix;
    matrix_float4x4 mvpMatrix = {
        .columns = {
            {mvpRawArray[0], mvpRawArray[1], mvpRawArray[2], mvpRawArray[3]},
            {mvpRawArray[4], mvpRawArray[5], mvpRawArray[6], mvpRawArray[7]},
            {mvpRawArray[8], mvpRawArray[9], mvpRawArray[10], mvpRawArray[11]},
            {mvpRawArray[12], mvpRawArray[13], mvpRawArray[14], mvpRawArray[15]}
        }
    };
    
    // 2. 目标3D局部坐标(示例为中心)
    vector_float3 target3DPoint = {0.0f, 0.0f, 0.0f};
    vector_float4 homogeneousPoint = {target3DPoint.x, target3DPoint.y, target3DPoint.z, 1.0f};
    
    // 3. 矩阵变换
    vector_float4 transformedPoint = matrix_multiply(mvpMatrix, homogeneousPoint);
    
    // 4. 透视除法
    float ndcX = transformedPoint.x / transformedPoint.w;
    float ndcY = transformedPoint.y / transformedPoint.w;
    
    // 5. 转换为屏幕坐标
    CGRect screenBounds = [UIScreen mainScreen].bounds;
    CGFloat screenX = (ndcX + 1.0f) * CGRectGetWidth(screenBounds) / 2.0f;
    CGFloat screenY = (1.0f - ndcY) * CGRectGetHeight(screenBounds) / 2.0f;
    
    NSLog(@"目标屏幕坐标:(%f, %f)", screenX, screenY);
}

注意事项

  • 自定义目标点:如果需要目标上的特定点(如右上角),只需替换target3DPoint为目标局部坐标系中的对应坐标(例如目标尺寸为1×1×0时,右上角为(0.5, 0.5, 0))。
  • 矩阵顺序:Vuforia返回的矩阵是列主序,代码中已正确处理,无需额外调整。
  • 坐标系适配:iOS屏幕原点在左上角,而NDC空间y轴向上,因此用1.0 - ndcY完成y轴翻转。

内容的提问来源于stack exchange,提问作者Macro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:05:28