← 返回总览cidaren 多视角三维重建

多视角三维重建课程项目报告

方法:MVS(多视角立体视觉)+ NeRF(神经辐射场),并尝试 3D Gaussian Splatting。 在不提供相机内外参的前提下,先用 COLMAP SFM 从图像中推测并导出相机参数,再分别用 MVS 与 NeRF 重建场景的密集点云表示。

1. 环境检查结果(本机 CUDA)

项目状态说明
操作系统Windows—
GPU✅ NVIDIA GeForce RTX 5060 Laptop GPU(8 GB,Blackwell/sm_120)nvidia-smi 可识别
NVIDIA 驱动 / CUDA✅ 驱动 592.01(CUDA 13.1 能力),nvcc 12.9CUDA Toolkit 12.9 已装
Python✅ 3.10.9(另存在 3.14.2)项目使用 3.10.9 虚拟环境
PyTorch✅ 2.9.0+cu129,torch.cuda.is_available() = True针对 Blackwell 选用 cu129 轮子
OpenCV✅ 4.12.0.88(系统)/5.0.0.93(venv)图像读取备用
numpy / scipy / matplotlib✅ 2.2.6 / 1.15.3 / 3.10.7数值与可视化
COLMAP✅ 4.2.1(with CUDA)已下载官方 Windows-CUDA 二进制
MSVC (cl.exe) / CMake / ninja❌ 均未安装见 §5 的 3DGS 阻塞说明
conda❌ 未安装使用 venv 代替

关键结论:CUDA + GPU 版 PyTorch 已就绪;深度学习训练在 GPU 上运行。


2. 数据集

mvs_project/ 为 Blender 4.5(Cycles+OptiX)渲染的合成数据集:

本项目严格遵守“不使用给定的相机参数”:重建只以 images/ 为输入,相机内外参全部由 COLMAP SFM 自行估计;transforms.json / sparse/ 仅用于结果校验。

3. 相机参数估计与导出(无先验)

用 COLMAP 走“特征提取 → 匹配 → 增量式 SFM”从纯图像恢复相机内外参:

colmap feature_extractor --database_path db.db --image_path images \
    --ImageReader.camera_model PINHOLE --ImageReader.single_camera 1
colmap exhaustive_matcher --database_path db.db
colmap mapper --database_path db.db --image_path images --output_path sparse
colmap model_converter --input_path sparse/0 --output_path cameras_export --output_type TXT

结果:

指标估计值真值误差
注册图像67 / 7272—
稀疏 3D 点6413——
平均重投影误差0.51 px——
fx900.40888.89+11.5 px(1.3%)
fy901.11888.89+12.2 px(1.4%)
cx / cy400.00 / 400.00400 / 4000

导出文件(output/colmap/cameras_export/):

自检:用本数据集 sparse/images.txt 与 transforms.json 交叉验证,二者 c2w 最大偏差 1.14e-6,证明导出/解析的坐标变换数学正确。COLMAP 恢复的轨迹与真值存在一定程度的 bas-relief(尺度/深度漂移),这是无先验 SFM 在“近环形环绕”序列上的固有 gauge 自由度, 但平均重投影误差 0.51 px 表明重建在二维层面自洽、可靠。

4. 方法一:MVS(多视角立体视觉)

4.1 路线

  1. COLMAP SFM(§3)估计相机内外参;
  2. 自编平面扫描(plane-sweep)MVS(PyTorch/CUDA)做密集深度估计并融合成点云。
说明:COLMAP 自带的 patch_match_stereo 在本机 Blackwell(sm_120) GPU 上无法产出深度图 (其 CUDA 核在该架构上静默失败,详见 §5 同类问题),因此采用“自己编写 MVS 算法” (课程要求允许)实现密集重建,这也是对 MVS 原理的直接实践。

4.2 平面扫描 MVS 实现(scripts/mvs_planesweep.py)

4.3 结果

分辨率不足,地面覆盖偏少,故全场景 recall 偏低;物体本身精度良好。


5. 方法二:NeRF(自编 PyTorch 实现)

5.1 实现(nerf/nerf_train.py)

5.2 结果


6. 方法三:3D Gaussian Splatting(尝试 → 未选用)

尝试记录:

栅格化)与 simple-knn 两个 CUDA 扩展,二者都必须用 MSVC 编译器(cl.exe)+ CMake 编译;

CMake 亦未安装;git clone(schannel)在沙箱中同样被禁用;

因缺少 MSVC 构建工具链而无法编译(同时该脚本亦验证了 cl.exe/cmake/ninja 的缺失)。

结论:3DGS 的 CUDA 栅格化扩展无法在本机编译,且官方未提供 Windows 预编译轮子;在课程要求

“尝试三种、实现两种”的前提下,最终选择 MVS 与 NeRF 两条进行实现,3DGS 记录为“已尝试、因

缺少 MSVC 构建工具链而阻塞”。


7. 评估(与真值对比)

指标:双向 Chamfer 距离(cm),对齐方式 = 相机中心相似变换 + ICP。

“物体区域”为剔除地面平面(z>0.3)后的对比,用于衡量静物本身的重建精度。

方法全场景 Chamfer物体区域 Chamfer物体区域 recon→GT物体区域 GT→recon
MVS(自编平面扫描)178.6 cm21.3 cm13.7 cm28.8 cm
NeRF(自编 PyTorch)169.4 cm19.2 cm17.8 cm20.5 cm

分析:

覆盖不足;② 无先验 COLMAP SFM 在“近环形环绕”序列上的固有 bas-relief 尺度/深度漂移

(相机中心对齐后 RMS ≈ 4.5 m),这一 gauge 自由度同时影响两条方法的世界系绝对精度。


8. 文件清单

report.md                          # 本报告
mvs_project/                       # 输入数据(只读)
tools/                             # COLMAP 二进制、torch 轮子
output/
├── colmap/                        # SFM:db.db、sparse/、cameras_export/、dense/
├── mvs/mvs_pointcloud.ply         # 方法一:MVS 密集点云
├── nerf/                          # 方法二:NeRF 检查点、点云
└── eval/                          # 评估指标、渲染图、对齐点云
scripts/
├── export_cameras.py              # 相机参数导出 + 校验
├── diag_poses.py                  # 位姿正确性自检
├── mvs_planesweep.py              # 自编平面扫描 MVS
├── eval_pointclouds.py            # Chamfer/ICP 评估
├── render_pc.py                   # 点云渲染
└── attempt_3dgs.py                # 3DGS 尝试记录
nerf/nerf_train.py                 # 自编 NeRF

9. 结论