CropFrameOpenSource 是一个基于 SwiftUI 和 RealityKit 构建的 Apple Vision Pro 沉浸式取景框应用,专注于双目摄影与立体视觉技术。其核心目标是通过手势驱动的取景框控制、头部追踪、四边形透视变换与立体照片生成,为用户提供直观、沉浸式的双目摄影体验。
项目主要特性包括:
- 手势驱动的取景框控制:通过双手食指与拇指中心点定位,实现对取景框的捏合、拖拽与旋转,无需物理控制器。
- 头部追踪:实时获取设备在世界坐标系中的姿态,确保取景框与用户头部运动同步。
- 四边形透视变换:将三维取景框的四个角点投影到双目相机的二维图像平面,形成可裁切的四边形区域。
- 立体照片生成:对左右眼图像进行四边形裁切与透视矫正,输出可用于立体显示的双目图像。
技术栈选择的优势:
- SwiftUI:声明式 UI 开发,便于快速迭代与跨界面一致性;结合 RealityKit 的沉浸式空间场景管理。
- RealityKit:强大的 3D 渲染与场景管理能力,支持沉浸式空间、实体与修饰器的组合使用。
- ARKit:提供世界跟踪与相机访问权限,支撑头部姿态与双目相机帧流的稳定获取。
- CoreImage:高性能图像处理与透视变换,保证裁切与投影过程的流畅与准确。
应用场景与价值:
- 影视与媒体制作:在沉浸式环境中精确构图与拍摄立体素材。
- 教育与培训:通过立体视觉增强教学与演示效果。
- 科研与测量:利用双目视觉进行三维重建与距离测量。
- 创意内容创作:为 VR/AR 内容创作者提供高效的取景与拍摄工具。
项目采用按功能域划分的模块化组织方式,核心目录与职责如下:
- CropFrame:应用入口与资源
- CropFrameApp.swift:应用入口,定义窗口与沉浸式空间场景。
- ContentView.swift:主界面,包含设置与沉浸式空间入口。
- ImmersiveView.swift:沉浸式空间主视图,承载 RealityKit 场景与取景框系统。
- AppModel.swift:应用级状态管理(沉浸式空间状态)。
- Info.plist 与 CropFrame.entitlements:系统配置与权限声明。
- Content/Models:核心业务模型
- CameraWithHead:双目相机帧采集与降噪、拍照流程。
- QuadrilateralCropper:四边形裁切与透视矫正。
- 3DTo2DProjector:三维点到二维像素的投影计算。
- Foundations:线性代数、手控点与头部姿态等基础工具。
- Content/Views:界面与视图
- ViewfinderUI:取景框 UI 与姿态系统(未在当前上下文展开)。
- Photos:照片展示与立体材质(未在当前上下文展开)。
- Assets.xcassets:应用图标与资源。
graph TB
subgraph "应用入口"
A["CropFrameApp<br/>应用入口"]
B["ContentView<br/>主界面"]
C["ImmersiveView<br/>沉浸式空间"]
D["AppModel<br/>应用状态"]
end
subgraph "取景框系统"
E["ViewfinderPack<br/>打包与协调"]
F["ViewfinderOrnamentSystem<br/>取景框UI与姿态"]
G["PhotosModel<br/>照片呈现"]
end
subgraph "相机与图像处理"
H["CameraWithHead<br/>双目相机帧采集"]
I["QuadrilateralCropper<br/>四边形裁切"]
J["ThreeDTo2DProjector<br/>3D→2D投影"]
end
subgraph "基础工具"
K["LinearAlgebra<br/>坐标变换"]
L["HandControlPointModel<br/>手控点"]
M["HeadAxisModel<br/>头部姿态"]
end
A --> B
A --> C
B --> D
C --> E
E --> F
E --> H
E --> G
E --> J
H --> I
J --> I
F --> J
F --> L
F --> M
H --> K
J --> K
图表来源
- CropFrameApp.swift
- ContentView.swift
- ImmersiveView.swift
- AppModel.swift
- ViewfinderPack.swift
- CameraWithHead.swift
- Cropper.swift
- Projector.swift
- LinearAlgebra.swift
- HandControlPointModel.swift
- HeadModel.swift
章节来源
- CropFrameApp.swift
- ContentView.swift
- ImmersiveView.swift
- AppModel.swift
- Info.plist
- CropFrame.entitlements
- 应用入口与场景管理
- CropFrameApp:定义窗口组与沉浸式空间,注入 AppModel 状态。
- ContentView:提供设置面板与沉浸式空间入口按钮。
- ImmersiveView:在 RealityKit 中添加世界原点与 ViewfinderPack,并监听沉浸式空间开闭状态。
- AppModel:维护沉浸式空间状态机(关闭/过渡/打开)。
- 取景框系统
- ViewfinderPack:对外统一接口,协调取景框 UI、相机与照片呈现。
- ViewfinderOrnamentAndCameraAndPhotos:内部编排,负责运行取景框系统、启动相机、获取内外参、触发拍照与裁切。
- 相机与图像处理
- CameraWithHead:启动 ARKit 会话与相机帧提供器,持续缓存最新帧,拍照时进行降噪并返回左右眼图像与头部姿态。
- QuadrilateralCropper:在后台线程执行透视矫正,支持宽松/普通/严格三种裁切严格度。
- ThreeDTo2DProjector:根据设备姿态与相机内外参,将三维角点投影到二维像素坐标。
- Foundations:线性代数工具、手控点与头部姿态模型,支撑坐标变换与姿态获取。
- 权限与配置
- Info.plist:声明沉浸式空间与多场景支持。
- CropFrame.entitlements:启用主摄像头访问权限。
章节来源
- CropFrameApp.swift
- ContentView.swift
- ImmersiveView.swift
- AppModel.swift
- ViewfinderPack.swift
- CameraWithHead.swift
- Cropper.swift
- Projector.swift
- LinearAlgebra.swift
- HandControlPointModel.swift
- HeadModel.swift
- Info.plist
- CropFrame.entitlements
系统采用“打包器 + 子系统”的分层架构:
- ViewfinderPack 作为对外接口,封装取景框 UI、相机与照片模块。
- ViewfinderOrnamentAndCameraAndPhotos 负责生命周期与流程编排:启动取景框系统、获取相机内外参、启动相机帧提供器、响应快门手势、执行裁切与呈现。
- ThreeDTo2DProjector 将三维角点投影到二维像素,供 QuadrilateralCropper 裁切使用。
- CameraWithHead 提供高质量双目帧与头部姿态,配合降噪与格式转换。
- Foundations 提供线性代数与手控点/头部姿态基础能力。
graph TB
VP["ViewfinderPack"] --> VF["ViewfinderOrnamentSystem"]
VP --> CAM["CameraWithHead"]
VP --> PH["PhotosModel"]
VP --> PRJ["ThreeDTo2DProjector"]
PRJ --> ALG["LinearAlgebra"]
VF --> HAND["HandControlPointModel"]
VF --> HEAD["HeadAxisModel"]
CAM --> COREIMG["CoreImage"]
图表来源
- ViewfinderPack.swift
- CameraWithHead.swift
- Projector.swift
- LinearAlgebra.swift
- HandControlPointModel.swift
- HeadModel.swift
该流程从用户手势触发到最终呈现立体照片,涉及取景框姿态获取、相机帧采集、投影与裁切、以及照片呈现。
sequenceDiagram
participant U as "用户"
participant VF as "ViewfinderOrnamentSystem"
participant VP as "ViewfinderPack"
participant CAM as "CameraWithHead"
participant PRJ as "ThreeDTo2DProjector"
participant CROP as "QuadrilateralCropper"
participant PH as "PhotosModel"
U->>VF : "手势捏合/拖拽取景框"
VF-->>VP : "回调 : 取景框姿态与角点"
VP->>PRJ : "请求 : 三维角点投影到二维"
PRJ-->>VP : "返回 : 二维四边形角点"
VP->>CAM : "请求 : takePhoto()"
CAM-->>VP : "返回 : 左右眼图像 + 头部姿态"
VP->>CROP : "裁切 : 左右眼图像"
CROP-->>VP : "返回 : 裁切后的图像"
VP->>PH : "呈现 : 立体照片"
图表来源
章节来源
该组件负责将三维取景框映射到二维图像平面,并进行透视矫正与裁切,支持宽松/普通/严格三种严格度。
flowchart TD
Start(["开始"]) --> GetQ["获取四边形角点<br/>与图像尺寸"]
GetQ --> Validate["按严格度验证四边形"]
Validate --> |宽松| Crop["透视矫正裁切"]
Validate --> |普通| Intersect{"与图像相交?"}
Intersect --> |是| Crop
Intersect --> |否| Error1["抛出无交集错误"]
Validate --> |严格| Inside{"完全在图像内?"}
Inside --> |是| Crop
Inside --> |否| Error2["抛出未完全包含错误"]
Crop --> Done(["结束"])
Error1 --> Done
Error2 --> Done
图表来源
章节来源
该组件将三维取景框角点投影到左右眼相机的二维像素坐标,依赖设备姿态与相机内外参。
classDiagram
class ThreeDTo2DProjector {
+camera : Device.Camera
+intrinsicsAndExtrinsics : IntrinsicsAndExtrinsics
+to2DCornersPoint(cornersPose, head) Quadrilateral2D
}
class PerspectiveCameraData {
+simpleIntrinsic : SimpleCameraIntrinsic
+leftEyeCameraPose : Transform
+rightEyeCameraPose : Transform
+resolution : Size2D
}
class WorldToCamera {
+worldPointToCameraPixel(worldPoint, eye) Point2D
}
class LinearAlgebra {
+worldToLocal(point, head) Point3D
+makeMatrixSimplified(...) Transform
}
ThreeDTo2DProjector --> PerspectiveCameraData : "使用"
ThreeDTo2DProjector --> WorldToCamera : "委托"
WorldToCamera --> LinearAlgebra : "坐标变换"
图表来源
章节来源
- 手势追踪:通过 SpatialTrackingSession 获取左右手食指与拇指尖端锚点,计算中心点作为手控点。
- 头部姿态:通过 ARKit 世界跟踪获取设备在世界坐标系中的姿态,用于投影与裁切。
sequenceDiagram
participant SP as "SpatialTrackingSession"
participant HF as "HandControlPointModel"
participant HT as "HeadAxisModel"
participant PRJ as "ThreeDTo2DProjector"
SP->>HF : "提供手部锚点"
HF-->>PRJ : "返回手控点(世界坐标)"
HT->>PRJ : "提供头部姿态(Transform)"
PRJ-->>PRJ : "坐标变换与投影"
图表来源
章节来源
- 模块耦合
- ViewfinderPack 作为协调者,与 ViewfinderOrnamentSystem、CameraWithHead、PhotosModel、ThreeDTo2DProjector 存在直接依赖。
- ThreeDTo2DProjector 依赖 LinearAlgebra 进行坐标变换。
- CameraWithHead 依赖 ARKit 与 AVFoundation 获取相机帧与头部姿态。
- 外部依赖
- SwiftUI/RealityKit:UI 与沉浸式空间渲染。
- ARKit/AVFoundation:相机访问与世界跟踪。
- CoreImage:图像处理与透视矫正。
- 潜在循环依赖
- 当前结构清晰,未发现循环依赖;各模块职责单一,通过接口解耦。
graph LR
VP["ViewfinderPack"] --> VF["ViewfinderOrnamentSystem"]
VP --> CAM["CameraWithHead"]
VP --> PH["PhotosModel"]
VP --> PRJ["ThreeDTo2DProjector"]
PRJ --> ALG["LinearAlgebra"]
CAM --> AR["ARKit/AVFoundation"]
PRJ --> CI["CoreImage"]
图表来源
章节来源
- 相机帧处理策略
- 采用持续缓存最新帧并在拍照时进行降噪与格式转换,避免每帧处理带来的发热与卡顿。
- 图像处理优化
- 使用后台 Actor 与 CoreImage 执行透视矫正,避免阻塞主线程。
- 投影与裁切
- 仅在需要时进行投影与裁切,减少不必要的计算。
- 建议
- 在低端设备上可考虑降低分辨率或帧率以换取稳定性。
- 对噪声抑制参数进行动态调节,平衡画质与性能。
- 相机启动失败
- 现象:沉浸式空间自动关闭并提示错误。
- 排查:检查权限配置与授权状态,确认主摄像头访问权限已授予。
- 参考
- 无法获取内外参
- 现象:拍照前准备阶段失败。
- 排查:确认相机帧提供器可用且支持所需视频格式。
- 参考
- 投影点不可见
- 现象:取景框角点位于相机后方导致无法投影。
- 排查:调整取景框位置,确保角点在相机前方。
- 参考
- 裁切失败
- 现象:四边形与图像无交集或未完全包含。
- 排查:调整取景框范围或切换裁切严格度。
- 参考
章节来源
CropFrameOpenSource 通过 SwiftUI 与 RealityKit 的组合,构建了一个面向 Apple Vision Pro 的沉浸式双目取景框系统。其核心在于将手势控制、头部追踪、3D→2D 投影与四边形裁切有机结合,实现了从取景到输出的完整工作流。项目结构清晰、模块职责明确,适合初学者理解 AR/VR 开发的基本概念,也为有经验的开发者提供了可扩展的技术基础。
- 快速开始
- 在 Xcode 中打开工程,连接 Apple Vision Pro 设备。
- 运行应用,点击“进入沉浸式空间”,使用双手捏合取景框。
- 触发快门手势,等待照片呈现。
- 设置项
- 支持选择照片呈现模式(左眼/右眼/立体)。
- 开发建议
- 在沉浸式空间中优先使用修饰器与实体管理生命周期。
- 注意权限与隐私声明,确保主摄像头访问权限正确配置。