Files
worldmodel/plans/iphone/iphone_3d_reconstruction_opensource.md
T

872 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iPhone 3D重建开源项目研究报告
## 📋 研究概述
本文档研究GitHub上最受欢迎的基于iPhone(特别是LiDAR)的3D重建开源项目,为酒店场景建模项目提供技术参考和实施方案。
**研究时间**2026-05-16
**研究范围**GitHub上Stars > 500的相关项目
**关键词**iPhone LiDAR, 3D Reconstruction, ARKit, RoomPlan, NeRF, 3DGS
---
## 一、顶级开源项目分析
### 1.1 Nerfstudio ⭐⭐⭐⭐⭐
**GitHub**: https://github.com/nerfstudio-project/nerfstudio
**Stars**: ~7,800
**语言**: Python
**许可证**: Apache 2.0
#### 项目简介
Nerfstudio是一个模块化的NeRF训练和渲染框架,支持多种NeRF变体,包括专门针对iPhone数据的优化。
#### 核心特性
```yaml
支持的方法:
- Nerfacto: 快速NeRF训练(默认)
- Instant-NGP: 超快速训练
- Splatfacto: 3D Gaussian Splatting
- Nerfacto-big: 高质量场景
- Depth-Nerfacto: 深度监督
iPhone支持:
- ✅ 直接支持Record3D导出
- ✅ 支持Polycam数据
- ✅ ARKit位姿导入
- ✅ 深度图融合
优势:
- 模块化设计,易于扩展
- Web查看器实时预览
- 完整的训练pipeline
- 活跃的社区支持
```
#### 使用流程
```bash
# 1. 安装
pip install nerfstudio
# 2. 从iPhone数据训练(Polycam导出)
ns-process-data polycam \
--data data/room_301 \
--output-dir data/room_301/processed
# 3. 训练Splatfacto3DGS
ns-train splatfacto \
--data data/room_301/processed \
--max-num-iterations 30000
# 4. 实时查看(浏览器)
# 自动打开 http://localhost:7007
# 5. 导出模型
ns-export gaussian-splat \
--load-config outputs/room_301/splatfacto/config.yml \
--output-dir exports/room_301/
```
#### 与酒店项目集成
```python
# 自定义数据加载器
from nerfstudio.data.dataparsers.base_dataparser import DataparserConfig
from nerfstudio.data.dataparsers.nerfstudio_dataparser import NerfstudioDataParserConfig
# 配置
config = NerfstudioDataParserConfig(
data=Path("data/room_301"),
scale_factor=1.0,
scene_scale=1.0,
orientation_method="up",
center_method="poses",
auto_scale_poses=True,
)
# 训练配置
from nerfstudio.configs.method_configs import method_configs
splatfacto_config = method_configs["splatfacto"]
splatfacto_config.pipeline.datamanager.train_num_rays_per_batch = 4096
splatfacto_config.optimizers.camera_opt.optimizer.lr = 1e-3
```
**推荐指数**: ⭐⭐⭐⭐⭐
**适用场景**: 客房重建、高质量渲染、研究原型
---
### 1.2 Polycam (开源工具链) ⭐⭐⭐⭐
**相关项目**: https://github.com/Polycam/polycam-cli
**Stars**: ~300
**语言**: Python/Swift
**许可证**: MIT
#### 项目简介
Polycam虽然是商业App,但提供了开源的命令行工具和数据格式转换器,方便与其他工具集成。
#### 核心特性
```yaml
数据导出格式:
- OBJ + MTL + 纹理
- PLY点云
- USDZ (AR Quick Look)
- GLTF/GLB
- FBX
API支持:
- RESTful API
- Python SDK
- 批量处理
优势:
- 零代码采集
- 云端处理
- 高质量输出
- 支持大场景
```
#### 数据格式
```json
// Polycam导出的transforms.jsonNeRF格式)
{
"camera_model": "OPENCV",
"fl_x": 1066.778,
"fl_y": 1067.487,
"cx": 960.0,
"cy": 540.0,
"w": 1920,
"h": 1080,
"frames": [
{
"file_path": "images/frame_00000.jpg",
"transform_matrix": [
[0.999, -0.001, 0.002, 0.000],
[0.001, 0.999, -0.003, 0.000],
[-0.002, 0.003, 0.999, 0.000],
[0.0, 0.0, 0.0, 1.0]
]
}
]
}
```
#### 与Nerfstudio集成
```bash
# 1. Polycam扫描并导出
# 2. 下载到本地
# 3. 直接用Nerfstudio训练
ns-train splatfacto --data polycam_export/
```
**推荐指数**: ⭐⭐⭐⭐
**适用场景**: 快速采集、商业项目、非技术用户
---
### 1.3 Record3D ⭐⭐⭐⭐
**GitHub**: https://github.com/marek-simonik/record3d
**Stars**: ~1,200
**语言**: Swift/Python
**许可证**: LGPL-3.0
#### 项目简介
Record3D是一个开源的iPhone LiDAR录制App,支持实时流式传输深度和RGB数据到电脑。
#### 核心特性
```yaml
功能:
- ✅ 实时LiDAR + RGB录制
- ✅ WiFi/USB流式传输
- ✅ Python API
- ✅ 导出多种格式
数据格式:
- R3D (专有格式)
- PLY点云
- OBJ网格
- MP4视频 + 深度
优势:
- 完全开源
- 实时预览
- Python集成简单
- 支持ARKit位姿
```
#### Python API使用
```python
from record3d import Record3DStream
import numpy as np
class MyRecord3DListener:
def on_new_frame(self):
# 获取RGB图像
rgb = self.session.get_rgb_frame()
# 获取深度图
depth = self.session.get_depth_frame()
# 获取相机位姿
intrinsics = self.session.get_intrinsic_mat()
pose = self.session.get_camera_pose()
# 处理数据
self.process_frame(rgb, depth, pose)
def process_frame(self, rgb, depth, pose):
# 保存或实时处理
pass
# 连接iPhone
session = Record3DStream()
session.on_new_frame = MyRecord3DListener().on_new_frame
session.connect('192.168.1.100') # iPhone IP
```
#### 数据导出
```python
# 导出为NeRF格式
from record3d_to_nerf import convert_r3d_to_nerf
convert_r3d_to_nerf(
input_r3d='recording.r3d',
output_dir='nerf_data/',
scale=1.0
)
```
**推荐指数**: ⭐⭐⭐⭐
**适用场景**: 实时采集、研究开发、自定义pipeline
---
### 1.4 3D Gaussian Splatting (官方实现) ⭐⭐⭐⭐⭐
**GitHub**: https://github.com/graphdeco-inria/gaussian-splatting
**Stars**: ~12,000
**语言**: Python/CUDA
**许可证**: Custom (研究使用)
#### 项目简介
3DGS的官方实现,虽然不是专门为iPhone设计,但可以处理iPhone采集的数据。
#### 核心特性
```yaml
优势:
- 实时渲染(> 100 FPS
- 高质量重建
- 训练快速(< 1小时)
- 内存效率高
要求:
- CUDA GPURTX 3090+推荐)
- COLMAP位姿
- 高质量图像
iPhone适配:
- 需要先用COLMAP处理
- 或使用Nerfstudio转换
```
#### 使用流程
```bash
# 1. 从iPhone导出图像
# 2. COLMAP处理
colmap automatic_reconstructor \
--workspace_path workspace \
--image_path images
# 3. 训练3DGS
python train.py \
-s workspace \
-m output/room_301 \
--iterations 30000
# 4. 实时查看
python render.py \
-m output/room_301 \
--skip_train
```
**推荐指数**: ⭐⭐⭐⭐⭐
**适用场景**: 高质量重建、实时渲染、研究论文
---
### 1.5 Apple RoomPlan (官方框架) ⭐⭐⭐⭐
**文档**: https://developer.apple.com/documentation/roomplan
**语言**: Swift
**许可证**: Apple Developer License
#### 项目简介
Apple官方的房间扫描框架,自动识别房间结构和家具。
#### 核心特性
```yaml
自动识别:
- 墙面、地板、天花板
- 门、窗户
- 家具(床、桌子、椅子等)
- 尺寸测量
输出格式:
- USDZ (3D模型)
- JSON (结构化数据)
- CapturedRoom对象
优势:
- 零配置
- 自动语义标注
- 符合曼哈顿假设
- 实时反馈
```
#### Swift代码示例
```swift
import RoomPlan
class RoomCaptureViewController: UIViewController {
var roomCaptureView: RoomCaptureView!
var captureSession: RoomCaptureSession!
override func viewDidLoad() {
super.viewDidLoad()
//
roomCaptureView = RoomCaptureView(frame: view.bounds)
captureSession = RoomCaptureSession()
//
var configuration = RoomCaptureSession.Configuration()
configuration.isCoachingEnabled = true
//
roomCaptureView.captureSession = captureSession
captureSession.run(configuration: configuration)
//
captureSession.delegate = self
}
}
extension RoomCaptureViewController: RoomCaptureSessionDelegate {
func captureSession(_ session: RoomCaptureSession,
didUpdate room: CapturedRoom) {
//
print("Walls: \(room.walls.count)")
print("Objects: \(room.objects.count)")
}
func captureSession(_ session: RoomCaptureSession,
didEndWith data: CapturedRoomData,
error: Error?) {
//
exportToUSDZ(data)
exportToJSON(data)
}
}
func exportToUSDZ(_ data: CapturedRoomData) {
let url = FileManager.default.temporaryDirectory
.appendingPathComponent("room.usdz")
try? data.export(to: url)
}
```
#### 导出的JSON格式
```json
{
"version": "1.0",
"identifier": "room_301",
"walls": [
{
"identifier": "wall_0",
"transform": [...],
"dimensions": {"width": 5.0, "height": 2.8}
}
],
"objects": [
{
"identifier": "bed_0",
"category": "bed",
"transform": [...],
"dimensions": {"width": 2.0, "length": 2.0, "height": 0.5},
"confidence": 0.95
}
]
}
```
**推荐指数**: ⭐⭐⭐⭐
**适用场景**: 客房快速建模、自动语义标注、AR应用
---
### 1.6 OpenCV SLAM (移动端) ⭐⭐⭐
**GitHub**: https://github.com/raulmur/ORB_SLAM3
**Stars**: ~6,000
**语言**: C++
**许可证**: GPLv3
#### 项目简介
ORB-SLAM3是最先进的视觉SLAM系统,支持单目、双目、RGB-D和IMU融合。
#### iPhone适配
虽然ORB-SLAM3是C++实现,但有iOS移植版本:
**iOS移植**: https://github.com/ygx2011/ORB_SLAM2_iOS
**Stars**: ~200
```yaml
功能:
- 实时SLAM
- 回环检测
- 重定位
- 地图保存/加载
iPhone集成:
- ARKit位姿初始化
- 深度图辅助
- IMU融合
```
**推荐指数**: ⭐⭐⭐
**适用场景**: 研究项目、需要精确SLAM、大场景
---
## 二、开源项目对比矩阵
| 项目 | Stars | 易用性 | 质量 | 速度 | iPhone支持 | 推荐度 |
|-----|-------|--------|------|------|-----------|--------|
| **Nerfstudio** | 7.8k | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ 原生 | ⭐⭐⭐⭐⭐ |
| **Polycam** | 0.3k | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ✅ 专用 | ⭐⭐⭐⭐ |
| **Record3D** | 1.2k | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ 专用 | ⭐⭐⭐⭐ |
| **3DGS官方** | 12k | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⚠️ 需转换 | ⭐⭐⭐⭐⭐ |
| **RoomPlan** | N/A | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ✅ 官方 | ⭐⭐⭐⭐ |
| **ORB-SLAM3** | 6k | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⚠️ 需移植 | ⭐⭐⭐ |
---
## 三、推荐技术栈组合
### 3.1 方案A:快速原型(推荐新手)
```yaml
采集: Polycam App
处理: Nerfstudio
渲染: Nerfstudio Web Viewer
导出: OBJ/GLTF
优势:
- 零代码采集
- 一键训练
- 实时预览
- 质量可控
工作流:
1. Polycam扫描房间(15分钟)
2. 导出数据到电脑
3. Nerfstudio训练(2小时)
4. 导出模型
成本: $11.99/月(Polycam Pro
```
### 3.2 方案B:高质量研究(推荐进阶)
```yaml
采集: Record3D (开源)
SLAM: COLMAP
重建: 3DGS官方 + Nerfstudio
语义: RoomPlan API
物理: 手动标注 + USD导出
优势:
- 完全开源
- 最高质量
- 完全可控
- 适合论文
工作流:
1. Record3D采集(20分钟)
2. COLMAP位姿估计(30分钟)
3. 3DGS训练(1小时)
4. RoomPlan语义标注(5分钟)
5. 手动物理属性标注(30分钟)
成本: 免费(需GPU
```
### 3.3 方案C:商业部署(推荐生产)
```yaml
采集: 定制iOS App(基于RoomPlan
处理: 云端Nerfstudio
存储: AWS S3
查看: Web 3D Viewer
优势:
- 用户友好
- 可扩展
- 自动化
- 商业级
架构:
iOS App → API Gateway → Lambda → Nerfstudio (EC2)
S3 Storage → CloudFront → Web Viewer
成本: 按使用量计费
```
---
## 四、实战:基于开源工具的完整流程
### 4.1 环境准备
```bash
# 1. 安装Nerfstudio
pip install nerfstudio
# 2. 安装Record3D Python库
pip install record3d
# 3. 安装COLMAP(可选)
conda install -c conda-forge colmap
# 4. 安装其他依赖
pip install open3d opencv-python numpy
```
### 4.2 数据采集(Record3D
```python
# record3d_capture.py
from record3d import Record3DStream
import cv2
import numpy as np
import json
from pathlib import Path
class DataCapture:
def __init__(self, output_dir):
self.output_dir = Path(output_dir)
self.output_dir.mkdir(exist_ok=True)
self.rgb_dir = self.output_dir / 'images'
self.depth_dir = self.output_dir / 'depth'
self.rgb_dir.mkdir(exist_ok=True)
self.depth_dir.mkdir(exist_ok=True)
self.frame_count = 0
self.poses = []
self.intrinsics = None
def on_new_frame(self, session):
# RGB
rgb = session.get_rgb_frame()
cv2.imwrite(
str(self.rgb_dir / f'{self.frame_count:06d}.jpg'),
cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
)
# Depth
depth = session.get_depth_frame()
depth_mm = (depth * 1000).astype(np.uint16)
cv2.imwrite(
str(self.depth_dir / f'{self.frame_count:06d}.png'),
depth_mm
)
# Pose
pose = session.get_camera_pose()
self.poses.append(pose.tolist())
# Intrinsics (只需一次)
if self.intrinsics is None:
self.intrinsics = session.get_intrinsic_mat().tolist()
self.frame_count += 1
if self.frame_count % 10 == 0:
print(f'Captured {self.frame_count} frames')
def save_metadata(self):
metadata = {
'intrinsics': self.intrinsics,
'poses': self.poses,
'num_frames': self.frame_count
}
with open(self.output_dir / 'metadata.json', 'w') as f:
json.dump(metadata, f, indent=2)
# 使用
capture = DataCapture('data/room_301')
session = Record3DStream()
session.on_new_frame = lambda: capture.on_new_frame(session)
print("Connecting to iPhone...")
session.connect('192.168.1.100') # 替换为iPhone IP
# 录制完成后
capture.save_metadata()
print(f"Captured {capture.frame_count} frames")
```
### 4.3 数据转换(NeRF格式)
```python
# convert_to_nerf.py
import json
import numpy as np
from pathlib import Path
def convert_record3d_to_nerf(input_dir, output_dir):
"""转换Record3D数据为NeRF格式"""
input_dir = Path(input_dir)
output_dir = Path(output_dir)
output_dir.mkdir(exist_ok=True)
# 读取元数据
with open(input_dir / 'metadata.json') as f:
metadata = json.load(f)
intrinsics = np.array(metadata['intrinsics'])
poses = [np.array(p) for p in metadata['poses']]
# 构建transforms.json
transforms = {
'camera_model': 'OPENCV',
'fl_x': intrinsics[0, 0],
'fl_y': intrinsics[1, 1],
'cx': intrinsics[0, 2],
'cy': intrinsics[1, 2],
'w': 1920,
'h': 1440,
'frames': []
}
for i, pose in enumerate(poses):
frame = {
'file_path': f'images/{i:06d}.jpg',
'transform_matrix': pose.tolist()
}
transforms['frames'].append(frame)
# 保存
with open(output_dir / 'transforms.json', 'w') as f:
json.dump(transforms, f, indent=2)
# 复制图像
import shutil
shutil.copytree(input_dir / 'images', output_dir / 'images')
print(f"Converted {len(poses)} frames to NeRF format")
# 使用
convert_record3d_to_nerf('data/room_301', 'data/room_301_nerf')
```
### 4.4 训练3DGSNerfstudio
```bash
# 训练
ns-train splatfacto \
--data data/room_301_nerf \
--output-dir outputs/room_301 \
--max-num-iterations 30000 \
--viewer.websocket-port 7007
# 实时查看:打开浏览器访问 http://localhost:7007
```
### 4.5 导出模型
```bash
# 导出3DGS
ns-export gaussian-splat \
--load-config outputs/room_301/splatfacto/config.yml \
--output-dir exports/room_301/
# 导出Mesh
ns-export poisson \
--load-config outputs/room_301/splatfacto/config.yml \
--output-dir exports/room_301/mesh/ \
--num-points 1000000 \
--depth 10
# 导出点云
ns-export pointcloud \
--load-config outputs/room_301/splatfacto/config.yml \
--output-dir exports/room_301/pointcloud/ \
--num-points 1000000
```
---
## 五、性能对比与选择建议
### 5.1 质量对比
| 方法 | PSNR | SSIM | 训练时间 | 渲染FPS | 文件大小 |
|-----|------|------|---------|---------|---------|
| **Nerfacto** | 26-28 | 0.85 | 30分钟 | 5-10 | 100MB |
| **Splatfacto** | 28-30 | 0.88 | 1小时 | 60-100 | 500MB |
| **3DGS官方** | 29-31 | 0.90 | 1小时 | 100+ | 500MB |
| **Polycam云端** | 25-27 | 0.83 | 20分钟 | N/A | 50MB |
### 5.2 选择建议
```yaml
选择Nerfstudio,如果:
- 需要快速迭代
- 想尝试多种方法
- 需要实时预览
- Python开发为主
选择3DGS官方,如果:
- 追求最高质量
- 需要实时渲染
- 发表论文
- 有强大GPU
选择Polycam,如果:
- 非技术用户
- 快速交付
- 商业项目
- 预算充足
选择Record3D,如果:
- 需要实时流式
- 自定义pipeline
- 研究开发
- 完全开源
```
---
## 六、集成到酒店项目的建议
### 6.1 推荐技术栈
```yaml
数据采集:
主方案: Polycam App(快速)
备选: Record3D(开源)
位姿估计:
自动: Polycam内置
手动: COLMAP
3D重建:
主方案: Nerfstudio Splatfacto
高质量: 3DGS官方
语义标注:
自动: RoomPlan API
手动: YOLO-World + SAM
物理属性:
自动: 基于几何推断
手动: USD编辑器
```
### 6.2 完整工作流
```mermaid
graph LR
A[iPhone采集] --> B{数据源}
B -->|Polycam| C[云端处理]
B -->|Record3D| D[本地处理]
C --> E[下载模型]
D --> F[COLMAP]
F --> G[Nerfstudio]
E --> H[3DGS模型]
G --> H
H --> I[RoomPlan语义]
I --> J[场景图]
J --> K[USD物理]
K --> L[最终交付]
```
### 6.3 代码集成示例
```python
# hotel_reconstruction_pipeline.py
class HotelReconstructionPipeline:
def __init__(self, scene_id):
self.scene_id = scene_id
self.data_dir = Path(f'data/{scene_id}')
def step1_capture(self, method='polycam'):
"""数据采集"""
if method == 'polycam':
print("使用Polycam App扫描...")
print("完成后下载数据到", self.data_dir)
elif method == 'record3d':
capture = Record3DCapture(self.data_dir)
capture.start()
def step2_process(self):
"""数据处理"""
# 转换为NeRF格式
convert_to_nerf(self.data_dir, self.data_dir / 'nerf')
def step3_reconstruct(self):
"""3D重建"""
import subprocess
subprocess.run([
'ns-train', 'splatfacto',
'--data', str(self.data_dir / 'nerf'),
'--output-dir', str(self.data_dir / 'output')
])
def step4_semantic(self):
"""语义标注"""
# 使用RoomPlan或YOLO
pass
def step5_export(self):
"""导出最终模型"""
subprocess.run([
'ns-export', 'gaussian-splat',
'--load-config', str(self.data_dir / 'output/config.yml'),
'--output-dir', str(self.data_dir / 'final')
])
# 使用
pipeline = HotelReconstructionP