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

如何从ARKit获取投影、旋转及平移矩阵?零基础入门指引

1. 如何从ARKit中获取投影矩阵、旋转矩阵及平移矩阵?

在ARKit中,所有和相机姿态、投影相关的数据都封装在ARFrame对象里,每一帧ARKit都会更新这个对象,你可以通过它轻松拿到需要的矩阵:

投影矩阵(Projection Matrix)

投影矩阵用于将3D世界坐标转换为2D屏幕坐标,你可以通过ARFrame的camera属性调用projectionMatrix(for:viewportSize:zNear:zFar:)方法获取:

guard let currentFrame = arView.session.currentFrame else { 
    print("当前没有可用的AR帧")
    return 
}
// 参数说明:
// - orientation:当前设备的方向(比如.portrait对应竖屏)
// - viewportSize:显示AR画面的视图尺寸
// - zNear/zFar:相机的近/远裁剪面范围(根据你的需求调整,比如0.01到1000)
let projectionMatrix = currentFrame.camera.projectionMatrix(
    for: .portrait, 
    viewportSize: arView.bounds.size, 
    zNear: 0.01, 
    zFar: 1000.0
)

旋转矩阵与平移矩阵

这两个矩阵其实是相机世界姿态的组成部分,ARKit用simd_float4x4类型的transform属性来存储相机在世界空间中的位置和旋转:

let cameraTransform = currentFrame.camera.transform

// 提取平移向量(相机在世界空间中的X/Y/Z位置)
let translation = cameraTransform.columns.3
let tx = translation.x
let ty = translation.y
let tz = translation.z

// 提取3x3旋转矩阵(描述相机的朝向)
let rotationMatrix = simd_float3x3(cameraTransform)

小提示:如果你需要将世界坐标转换到相机视角下的坐标,只需要取cameraTransform的逆矩阵即可;直接用transform拿到的是相机在世界中的姿态,适合后期处理时还原拍摄视角。


2. 从未接触过ARKit、Swift/Objective-C编程,需使用iPhone拍摄照片并读取对应矩阵用于后期处理,求最佳入门路径

作为从零开始的新手,我建议你按以下步骤稳扎稳打,不用急于求成:

第一步:搞定基础环境与Swift语法

  • 安装Xcode:直接从Mac App Store下载最新版Xcode,这是苹果官方的开发工具,包含了所有iOS开发需要的组件。花1小时熟悉Xcode的基本操作:创建项目、连接真机运行、查看控制台输出。
  • 学Swift核心语法:不用啃完厚厚的教程,先掌握变量/常量、函数、可选值、类、闭包这些基础(1-2天足够)。苹果官方的《Swift Programming Language》是最权威的入门材料,直接在Xcode的Help菜单里就能找到,跟着里面的示例敲代码就行。

第二步:创建第一个ARKit项目,获取帧数据

  • 打开Xcode,选择Create a new Xcode project,然后选Augmented Reality App模板,界面技术选SceneKit(虽然我们不需要3D场景,但这个模板已经帮你配置好了ARKit的基础环境),给项目起个名字比如ARPhotoCapture。
  • 把你的iPhone用数据线连到Mac,在Xcode顶部选择你的设备作为运行目标,点击运行按钮,此时你会看到手机上显示相机画面,ARKit已经在后台工作了。
  • 接下来修改代码获取ARFrame:在ViewController.swift里,找到session(_:didUpdate:)方法(如果模板里没有,就先让ViewController遵守ARSessionDelegate协议),每次ARKit更新帧时,就能拿到currentFrame,然后按照第一个问题里的代码提取矩阵。

第三步:实现拍照与数据保存

  • 拍摄照片:ARFrame的capturedImage属性是相机的原始帧数据,你可以把它转换成UIImage。示例代码:
    func capturePhoto(from frame: ARFrame) -> UIImage? {
        let imageBuffer = frame.capturedImage
        let ciImage = CIImage(cvImageBuffer: imageBuffer)
        let context = CIContext(options: [.useSoftwareRenderer: false])
        guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else {
            return nil
        }
        // 原始帧是横屏的,需要旋转到竖屏方向
        return UIImage(cgImage: cgImage, scale: 1.0, orientation: .right)
    }
    
  • 保存矩阵与照片:把矩阵转换成可存储的格式(比如JSON),和照片一起保存到手机的Documents目录。示例代码:
    func saveCaptureData(photo: UIImage, projectionMatrix: simd_float4x4, cameraTransform: simd_float4x4) {
        guard let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
            return
        }
        // 用时间戳生成唯一文件名,避免重复
        let timestamp = Date().timeIntervalSince1970
        let photoURL = documentsDir.appendingPathComponent("\(timestamp).jpg")
        let dataURL = documentsDir.appendingPathComponent("\(timestamp).json")
        
        // 保存照片
        if let photoData = photo.jpegData(compressionQuality: 0.8) {
            try? photoData.write(to: photoURL)
        }
        
        // 把4x4矩阵转成数组,方便转JSON
        let projectionArray = projectionMatrix.columns.flatMap { [$0.x, $0.y, $0.z, $0.w] }
        let transformArray = cameraTransform.columns.flatMap { [$0.x, $0.y, $0.z, $0.w] }
        let dataDict: [String: Any] = [
            "projection_matrix": projectionArray,
            "camera_transform": transformArray,
            "timestamp": timestamp
        ]
        
        // 保存JSON数据
        if let jsonData = try? JSONSerialization.data(withJSONObject: dataDict, options: .prettyPrinted) {
            try? jsonData.write(to: dataURL)
        }
    }
    
  • 添加拍摄按钮:打开Main.storyboard,拖一个UIButton到屏幕底部,关联到ViewController的IBAction方法,点击按钮时调用上面的capturePhoto和saveCaptureData方法。

第四步:导出数据到电脑做后期处理

  • 你可以通过Xcode的Window -> Devices and Simulators窗口,找到你的iPhone,点击Download Container导出App的Documents目录,里面就是你拍摄的照片和对应的JSON数据。
  • 后期处理时,比如用Python读取矩阵:
    import numpy as np
    import json
    
    with open("1698765432.json", "r") as f:
        data = json.load(f)
    # 把数组重新reshape成4x4矩阵
    projection_matrix = np.array(data["projection_matrix"]).reshape(4,4)
    camera_transform = np.array(data["camera_transform"]).reshape(4,4)
    

第五步:避坑小贴士

  • 别忘了在Info.plist里添加Privacy - Camera Usage Description键,填写相机权限的说明(比如“需要使用相机拍摄照片并获取AR数据”),不然App会直接崩溃。
  • 确保你的设备支持ARKit:iPhone 6s及以上机型,iOS 11及以上系统。
  • 获取投影矩阵时,要保证orientation参数和当前设备的方向一致,不然矩阵会不正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:19:41