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

Swift 3:如何访问48字节CFData中的matrix_float3x3值?

提取相机内参矩阵数值的两种方法

嘿,这个问题我之前做AR项目的时候刚好碰到过!既然你已经拿到了对应matrix_float3x3的CFData,而且知道它是列主序存储的,那有两种简单的方式来提取里面的数值:

方法一:直接绑定到matrix_float3x3结构体

这是最简洁的方式,利用Swift的内存绑定直接把数据映射成系统定义的矩阵结构体:

if let camData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) as? CFData {
    // 将CFData转为Swift的Data类型,方便内存操作
    let data = Data(camData)
    
    // 绑定内存到matrix_float3x3结构体
    data.withUnsafeBytes { buffer in
        guard let baseAddr = buffer.baseAddress else { return }
        let intrinsicMatrix = baseAddr.assumingMemoryBound(to: matrix_float3x3.self).pointee
        
        // 注意:matrix_float3x3是列主序存储,columns数组的每个元素代表一列
        let fx = intrinsicMatrix.columns.0.x  // 焦距x(第一列第一行)
        let fy = intrinsicMatrix.columns.1.y  // 焦距y(第二列第二行)
        let cx = intrinsicMatrix.columns.2.x  // 光心x(第三列第一行)
        let cy = intrinsicMatrix.columns.2.y  // 光心y(第三列第二行)
        
        print("相机内参:fx=\(fx), fy=\(fy), cx=\(cx), cy=\(cy)")
    }
}

matrix_float3x3的columns属性是三个SIMD3<Float>实例,每个实例对应矩阵的一列。比如columns.0是第一列,它的x、y、z分别对应矩阵第1、2、3行的元素。

方法二:手动解析字节提取Float数组

如果你更习惯直接操作原始数据,可以把CFData里的字节拷贝到Float数组中,再按列主序的规则提取元素:

if let camData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) as? CFData {
    let data = Data(camData)
    // 初始化一个能容纳9个Float的数组(3x3矩阵共9个元素)
    var floatArray = [Float](repeating: 0.0, count: 9)
    
    // 把Data中的字节拷贝到Float数组
    data.copyBytes(to: &floatArray, count: MemoryLayout<Float>.stride * 9)
    
    // 列主序的数组顺序是:[m11, m21, m31, m12, m22, m32, m13, m23, m33]
    // 对应行主序矩阵:
    // [m11, m12, m13]
    // [m21, m22, m23]
    // [m31, m32, m33]
    let fx = floatArray[0]  // m11
    let fy = floatArray[4]  // m22
    let cx = floatArray[6]  // m13
    let cy = floatArray[7]  // m23
    
    // 也可以转成行主序的二维数组方便查看
    let rowMajorMatrix = [
        [floatArray[0], floatArray[3], floatArray[6]],
        [floatArray[1], floatArray[4], floatArray[7]],
        [floatArray[2], floatArray[5], floatArray[8]]
    ]
    print("行主序矩阵:\(rowMajorMatrix)")
}

重要提醒

一定要记住这个矩阵是列主序存储的,和我们日常写矩阵的行主序习惯不一样。如果需要转换成行主序(比如传给Core ML模型或者其他用行主序的库),要注意元素的顺序转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:10:04