本课是模块二的第一节。前3节课已经建立了 NeRF 和 3DGS 的原理框架,现在进入「动手做」的阶段。
L1 你已经理解了 NeRF 的核心:5D 坐标 → MLP → 体积渲染 → 像素。现在的问题是:如何在真实数据上跑起来?
从零手写一个完整的 NeRF 训练管线,需要处理相机标定、数据加载、采样策略、损失计算、可视化等大量工程细节。这不是 Mission 的目标。nerfstudio 把这些都封装好了,让你专注于模型本身。
nerfstudio 是当前最成熟的 NeRF/3DGS 开源框架,核心优势有三:
以下是在 Linux + NVIDIA GPU 上的推荐安装流程。nerfstudio 要求 Python ≥ 3.8、CUDA 兼容的 PyTorch,以及 tiny-cuda-nn(用于 Instant-NGP 等方法的高效 CUDA kernel)。
# 1. 创建 conda 环境
conda create -n nerfstudio -y python=3.8
conda activate nerfstudio
# 2. 安装 PyTorch (CUDA 11.8 版本)
pip install torch==2.1.2+cu118 torchvision==0.16.2+cu118 \
--extra-index-url https://download.pytorch.org/whl/cu118
# 3. 安装 CUDA toolkit
conda install -c "nvidia/label/cuda-11.8.0" cuda-toolkit
# 4. 安装 tiny-cuda-nn
pip install ninja git+https://github.com/NVlabs/tiny-cuda-nn/\
#subdirectory=bindings/torch
# 5. 安装 nerfstudio
pip install nerfstudio
# 6. 启用命令行补全(可选但推荐)
ns-install-cli
CUDA 版本不匹配:PyTorch 和 tiny-cuda-nn 必须用相同 CUDA 版本编译。如果报错,先确认 nvcc --version 和 PyTorch 的 CUDA 版本一致。
Windows 安装:nerfstudio 在 Windows 上问题较多,推荐 WSL2 或 Linux 环境。
nerfstudio 提供 6 个核心 CLI 命令,覆盖从数据到部署的全流程:
| 命令 | 作用 | 典型用法 |
|---|---|---|
ns-process-data | 从图片/视频生成训练数据(含 COLMAP 位姿估计) | ns-process-data images --data images/ --output-dir data/custom/ |
ns-train | 训练模型 | ns-train nerfacto --data data/custom/ |
ns-viewer | 启动 Web Viewer 查看训练好的模型 | ns-viewer --load-config outputs/.../config.yml |
ns-eval | 评估模型质量(PSNR/SSIM/LPIPS) | ns-eval --load-config outputs/.../config.yml |
ns-render | 渲染视频或图片序列 | ns-render --load-config ... --traj spiral |
ns-export | 导出点云、网格、高斯点云等 | ns-export pointcloud --load-config ... |
下面用 nerfstudio 自带的 poster 数据集完成一个完整流程。这个数据集是室内场景,包含约 200 张图像,适合初次实验。
ns-download-data nerfstudio --capture-name=poster
数据会被下载到 data/nerfstudio/poster/,目录结构如下:
data/nerfstudio/poster/
├── images/ # 原始图像
├── transforms.json # COLMAP 标定的相机位姿和内参
└── ...
ns-train nerfacto --data data/nerfstudio/poster
训练启动后,终端会显示实时指标,同时自动打开 Web Viewer(默认端口 7007)。
nerfacto 是 nerfstudio 的默认模型,不是原始 NeRF。它整合了多个改进:
简单来说,nerfacto ≈ NeRF + Instant-NGP + Mip-NeRF 360 的工程融合。它是真实世界场景的最佳起点。
打开终端输出的 Viewer URL(如 http://localhost:7007),你可以:
训练完成后,用测试集评估 PSNR、SSIM、LPIPS:
ns-eval --load-config outputs/poster/nerfacto/.../config.yml \
--output-path eval.json
用你自己的照片训练 NeRF,需要先做两件事:位姿估计(每张照片的相机位置和朝向)和 数据格式化。
# 从图片文件夹生成训练数据
ns-process-data images \
--data path/to/your/images/ \
--output-dir data/custom-scene/
# 从视频生成(自动抽帧)
ns-process-data video \
--data path/to/video.mp4 \
--output-dir data/custom-scene/ \
--num-frames-target 200
ns-process-data 内部会自动运行 COLMAP(Structure from Motion 工具),完成:
transforms.json(nerfstudio 需要的格式)对策:增加拍摄角度变化、避免大面弱纹理、移除动态元素。若 COLMAP 仍然失败,可考虑使用 HLoc 等替代工具。
nerfacto 的默认参数已经过大量场景调优,通常无需修改。但遇到以下情况时可以针对性调整:
| 参数 | 作用 | 何时调整 | 典型值 |
|---|---|---|---|
--pipeline.datamanager.train-num-rays-per-batch | 每批次采样射线数 | 显存不足/过剩时 | 2048–8192(默认 4096) |
--pipeline.model.num-levels | 哈希编码层级数 | 场景复杂度变化时 | 12–16(默认 16) |
--pipeline.model.hidden-dim | MLP 隐藏层维度 | 需要更高/更低精度时 | 64–128(默认 64) |
--trainer.steps-per-save | 保存 checkpoint 的间隔 | 磁盘空间有限时 | 2000(默认) |
--optimizers.fields.lr | 场景 MLP 的学习率 | 训练不稳定时 | 1e-2(默认) |
--max-num-iterations | 最大迭代次数 | 场景复杂度变化时 | 30000(默认) |
一个显存受限时的调参示例:
ns-train nerfacto \
--pipeline.datamanager.train-num-rays-per-batch 2048 \
--pipeline.model.hidden-dim 32 \
--max-num-iterations 20000 \
--data data/custom-scene/
nerfstudio 使用三个标准指标评估重建质量:
实际调优时,建议优先关注 LPIPS。一个模型可能 PSNR 很高但 LPIPS 很差(意味着图像「看起来不对」)。
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 重建结果模糊、缺乏细节 | 训练不足;哈希层级不够;位姿不准 | 增加迭代次数;提高 num-levels;检查 COLMAP 质量 |
| 出现「鬼影」(运动模糊痕迹) | 场景中有移动物体;拍摄时手抖 | 移除动态元素;使用三脚架;减少相邻帧重叠 |
| 天空/白色区域出现 artifact | 弱纹理区域 COLMAP 位姿不准 | 避免大面积纯色;增加其他角度覆盖 |
| 训练 loss 不下降 | 学习率过大;数据损坏 | 降低学习率;检查 transforms.json 格式 |
| Viewer 无法连接 | 端口被占用;远程机器未做端口转发 | 更换端口 --viewer.websocket-port 7008;配置 SSH 隧道 |
ns-train --help 能正常输出。ns-eval 评估 poster 模型,记录 PSNR、SSIM、LPIPS。train-num-rays-per-batch 为 2048 和 8192 分别训练,对比训练速度和最终质量。如果在安装、训练或调优过程中遇到任何问题,随时问我。我可以帮你排查报错、解释参数含义,或讨论特定场景的拍摄策略。