一款基于 AI 的实时智能构图相机应用,通过动态引导帮助用户轻松拍出构图专业的照片。
智能手机拍照功能强大,但大多数普通用户并不了解"三分法"等专业构图知识,拍出的照片往往构图平庸、主体不突出。现有相机应用大多只提供静态九宫格辅助线,无法主动告知用户"应该怎么移动手机才能构图更好"。
LiveCompose 通过 AI 技术实时分析画面内容,主动引导用户移动手机以获得更优良的构图,并在对齐时自动完成拍摄——让好照片的诞生更加"智能"和"轻松"。
目标用户: 希望提高手机摄影水平、但缺乏专业摄影知识的广大普通用户(如喜欢在社交媒体分享生活的年轻人、希望为家人拍出更好照片的父母等)。
核心目标: 成为一个"智能构图助手",通过实时反馈和引导,帮助用户在拍摄当下就完成出色的构图。
用户收益:
- 照片构图质量显著改善,画面主体更突出,视觉效果更专业
- 在拍摄过程中潜移默化地学习构图技巧
- 开启自动拍照功能后,可更专注于捕捉对象的表情和动作,捕捉更自然的瞬间
| 对比维度 | 传统相机应用 | LiveCompose |
|---|---|---|
| 构图辅助 | 静态九宫格网格线 | AI 实时动态引导 |
| 用户交互 | 被动参考 | 主动追踪 + 磁性吸附 |
| 拍摄触发 | 手动按快门 | 对齐后自动拍摄 |
| 传感器融合 | 无 | 陀螺仪 + AI 模型联合追踪 |
核心优势: "检测 → 追踪 → 引导 → 拍摄"的完整闭环,结合设备陀螺仪数据实现物理上更准确、体验更流畅的追踪系统,大大降低操作门槛,实现摄影的普惠化与大众化。
系统采用四层架构设计,各层之间通过明确的接口通信:
┌─────────────────────────────────────────────────────────┐
│ 第四层:视图与交互层 (SwiftUI) │
│ ContentView / CameraPreview / UserGuidanceView / 控件 │
└────────────────────────┬────────────────────────────────┘
│ @Published 状态驱动
┌────────────────────────┴────────────────────────────────┐
│ 第三层:核心协调层 │
│ CaptureViewModel(状态机 / 调度中心) │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────┴────────────────────────────────┐
│ 第二层:智能决策与追踪层 │
│ AdacropModel(CoreML / 强化学习) │
│ BoxCenterManager(物理追踪 + 磁性吸附) │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────┴────────────────────────────────┐
│ 第一层:数据采集层 │
│ CameraManager(AVFoundation / 视频帧 / 拍照) │
│ MotionStabilityMonitor(CoreMotion / 陀螺仪) │
└─────────────────────────────────────────────────────────┘
各层职责:
- 数据采集层: 通过
CameraManager(AVFoundation)捕捉实时视频帧与拍摄最终照片;通过MotionStabilityMonitor(CoreMotion)持续获取陀螺仪和加速度数据。 - 智能决策与追踪层:
AdacropModel通过 CoreML 运行强化学习模型,分析视频帧并计算最佳构图建议;BoxCenterManager结合陀螺仪数据实现基于物理的目标追踪,并提供"磁性吸附"功能。 - 核心协调层:
CaptureViewModel管理复杂的状态机(等待稳定 → 检测中 → 追踪就绪 → 对齐成功 → 拍照),统一调度上下两层的协作。 - 视图与交互层: 完全由 SwiftUI 构建,订阅
CaptureViewModel的@Published属性,自动响应状态变化并渲染界面。
| 模块 | 结构 | 输入 | 输出 |
|---|---|---|---|
| Backbone | ResNet50(ImageNet 预训练,去掉 fc) | [B, 3, 224, 224] 图像张量 |
特征向量 [B, 2048] |
| Actor 分支 | MLP:2048+4 → 1024 → 512 → n_actions | 图片特征 + 当前裁剪框状态 (cx, cy, w, h) |
动作概率分布 [B, n_actions] |
| Critic 分支 | MLP:2048+4 → 1024 → 512 → 1 | 同 Actor | 当前状态价值估计 [B, 1] |
| BBox Head | MLP:2048 → 512 → 4(仅预训练阶段使用) | 图片特征 [B, 2048] |
预测裁剪框参数 [B, 4] |
输入预处理: 将图像最长边缩放至 224,短边用黑色填充,保持原始宽高比。
阶段一:监督预训练
- 输入图片,Backbone 提取特征
- BBox Head 回归裁剪框参数
- 用 MSELoss 与真实框做监督训练
- 训练结束后将 Backbone 和 BBox Head 的权重迁移至完整 ActorCritic 模型
目的: 让 Backbone 学会裁剪相关特征,为强化学习提供更好的初始化,减少冷启动阶段的随机探索。
阶段二:强化学习(Actor-Critic / PPO)
- 环境(CropEnv)状态: 当前裁剪图像张量
[3, img_size, img_size]+ 归一化几何向量[x/iw, y/ih, w/iw, h/ih] - 动作空间(11 个):
left, right, up, down, zoom_in, zoom_out, wider, narrower, taller, shorter, stop - 奖励设计:
- 基于 NIMA 美学模型分数变化:
base_reward = tanh(score_diff × 2.0) - 惩罚项:重复访问、连续无效动作(no-op)、过度重复
stop动作特殊奖励:(final_score - prev_score) × 2.0+ 早停惩罚/适时停奖励
- 基于 NIMA 美学模型分数变化:
- NIMA 评分策略: 每
real_score_interval(默认 5)步进行一次真实 NIMA 调用;其余步骤使用几何启发估计(基于黄金比例、面积偏好等),并结合缓存机制减少重复计算。 - Actor–Critic 协作: Actor 通过
policy_loss优化动作选择;Critic 通过value_loss预测累计奖励,为 Actor 提供稳定的基线,降低梯度方差。
数据集构建流程受 AAAI 2024 论文 "Learning Subject-Aware Cropping by Outpainting Professional Photos" 启发,采用双模型工作流自动扩充专业摄影数据:
工作流:
- 语义描述生成 — 使用
BLIP Image Captioning (base)为原始专业摄影图片生成准确的语义描述,作为扩图模型的上下文指导。 - 多样化扩图生成 — 使用
Stable Diffusion v2 Inpaint对上、下、左、右四个方向独立随机扩展(比例范围:10%–47.5%),并结合提示词相关性与迭代步数的组合变化,生成多样性丰富的扩展样本。 - 质量控制(三步):
- 边框伪影自动检测: 使用 Canny 边缘检测识别接缝处的"画框"伪影,自动丢弃不合格样本。
- 原图一致性校验: 反向裁剪验证 Inpaint 模型未污染被 Mask 保护的原始区域。
- 人工快速筛选: 自动拼接多版本对比预览图,支持高效人工抽检。
最终产出: {扩展后图片, 原图坐标框} 二元组数据集。
图片裁剪本质上是一个多步微调的 Markov 决策过程(移动 / 缩放 / 调整比例 / 停止)。NIMA 评分函数与奖励不可微,策略梯度可绕过可微性限制;同时便于未来扩展动作空间(如旋转)。Actor–Critic 结构相较于纯策略梯度,Critic 可降低方差并加速收敛,在奖励噪声较大时尤为重要。
相机硬件 (60 FPS)
↓
AVCaptureSession(会话管理)
↓
AVCaptureVideoDataOutput(帧输出)
↓
captureOutput:didOutput:from:(回调)
↓
CMSampleBuffer(像素缓冲)
↓
CameraManager.onSampleBuffer(闭包传递)
↓
CaptureViewModel.handleSampleBuffer(业务处理)
├─ 稳定性检查(MotionStabilityMonitor)
├─ 3:4 构图裁切(CIImage & CIContext)
├─ Adacrop 模型检测(AdacropModel / CoreML)
└─ 追踪更新(BoxCenterManager)
↓
SwiftUI 视图更新(@Published 属性)
↓
用户界面渲染
选用 AVFoundation 原生框架而非第三方库(如 GPUImage),理由:
- 最低硬件性能损耗,充分利用苹果 ISP 硬件加速
- 串行队列设计保证线程安全
CameraManager在接收到 CoreMotion 的稳定信号后才拉取最新帧,避免模糊帧进入模型
CoreML 轻量化: Adacrop 模型从 PyTorch 版本蒸馏转译为 CoreML 的轻量化 Student 模型,继承教师端参数,在移动端拥有更高效的处理速度。
构图建议的生成和引导分为两个阶段:AI 分析找到最优构图 → 轻量级追踪系统引导用户复现。
追踪系统以构图模型返回的建议框中心点为目标,结合陀螺仪数据实时计算追踪点位移:
- 物理追踪: 随设备姿态变化平滑更新追踪点位置,呈现出"点能追踪物体"的视觉效果
- 磁性吸附: 当追踪点接近目标中心时自动吸附,辅助用户稳定对齐
- 自动拍摄: 两点对齐后追踪点变绿并锁定,自动向
CameraManager发送拍摄信号
| 目标 | 实现方式 |
|---|---|
| 状态可视化 | 动态文字引导 + 进度阶段映射 |
| 操作指引 | 情境化提示文字 + 画面视觉标记 |
| 反馈闭环 | 动态颜色渐变(白色 → 绿色)+ Haptic Engine 触觉震动 |
| 事件 | 反馈类型 | 用户感知 |
|---|---|---|
| 点击魔术棒开启流水线 | success() |
"功能已激活" |
| 检测到目标区域 | success() |
"识别成功" |
| 追踪点对齐中心 | focusLock() |
"对准了!"(双击震动) |
| 追踪点失去对齐 | warning() |
"偏离了"(警告震动) |
| 拍照触发 | capture() |
"快门按下"(双段震动) |
| 照片保存成功 | success() |
"任务完成" |
| 检测到大幅运动 | warning() |
"需要重新稳定" |
| 阶段 | 引导文字 | 设计意图 |
|---|---|---|
| 空闲 | 点击魔术棒开启智能构图 | 引导用户点击右下角的魔术棒 |
| 启动 | 正在启动相机 | 告知系统正在准备,减轻等待焦虑 |
| 等待稳定 | 请保持稳定 | 明确的动作指令(静止) |
| 检测中 | 正在识别最佳构图... | 解释延迟原因,传达智能感 |
| 追踪就绪 | 请将圆点移动到画面中心 | 具体的操作目标 |
| 对齐成功 | 即将拍照,请保持稳定 | 确认成功 + 持续要求 |
| 拍照中 | 正在拍照... | 避免用户重复触发 |
| 完成 | 照片已保存 | 积极反馈,任务闭环 |
| 错误 | 发生错误,请重试 | 友好的错误提示 |
- 三分构图线: 基础九宫格网格辅助用户将手机置平
- 运动重置: 设备移动速度过快时自动重置拍摄流程,避免模糊帧影响结果
| 阶段 | 屏幕显示 | 用户操作 | 系统后台 |
|---|---|---|---|
| 初始状态 | 点击魔术棒开启智能构图 | 点击右下角的魔术棒按钮 | Standby |
| 流水线激活 | 请保持稳定 | 尽量保持手机静止 | 开始监控设备稳定性 |
| Adacrop 检测中 | 正在识别最佳构图... | 尽量保持手机静止 | 调用模型返回构图建议 |
| 追踪就绪 | 请将圆点移动到画面中心 | 开始缓慢旋转/平移手机 | 追踪点跟随设备移动 |
| 追踪对齐中 | 颜色渐变:白色 → 绿色 | 正在接近目标 | 追踪点被中心点吸附 |
| 对齐成功 | 即将拍照,请保持稳定 | 尽量保持手机静止 | focusLock() 双击震动 |
| 拍照执行 | 正在拍照... | 尽量保持手机静止 | capture() 快门震动序列 |
| 保存成功 | 照片已保存 | — | 引导文字恢复初始状态 |
- NIMA 二次评分验证: 对比拍摄前后的美学评分,量化构图提升效果
- A/B 测试: 向用户同时展示原图与 AI 构图结果,通过问卷收集偏好数据
- 处理速度: 记录从帧采集到构图建议输出的端到端延迟
利用 iPhone Pro 的 LiDAR 传感器获取场景深度图,准确测量主体距离并用于自适应增益;结合深度边缘在复杂背景下提升人物分割精度(LiDAR 延迟 < 10ms,适合实时追踪场景)。
- 上传用户拍摄照片(匿名化处理)到云端,持续训练全局美学模型
- 模型定期推送更新到设备,跟随最新摄影趋势
- 社区优秀作品的构图参数作为预设供用户选择,构建"站在巨人肩膀上"的创作辅助生态
LiveCompose — 让每一张照片都拥有专业构图