从图片生成3维场景--NERF原理解析及加速版HashNeRF-pytorch代码实现

概要

NeRF(Neural Radiance Fields)是一种基于神经网络的三维图像生成技术,通过一组从不同角度拍摄的2D图片,生成一个3D场景,并且能够渲染出该场景在任意视角下的图像。这项技术的核心思想是利用神经网络的强大建模能力来预测三维空间中每一点的光照和颜色。

Instant-NGP 为NERF引入了多分辨率哈希编码。原始的 NVIDIA 实现主要基于 C++/CUDA,基于 tiny-cuda-nn,可以使 NeRF 训练速度提高 100 倍!该项目是 Instant-NGP 的 纯 PyTorch 实现,旨在帮助 AI 研究人员进一步探索和创新此方法。

官方代码:https://github.com/yashbhalgat/HashNeRF-pytorch/

本人已打包好数据可直接运行代码: https://pan.baidu.com/s/1gJecCah5UGP1yRu-X1_G4A?pwd=yrqf 提取码: yrqf

NERF原理

NeRF的工作流程大致可以分为以下几个步骤:

  1. 输入数据

    NeRF需要从场景的不同角度获取一组2D图像及其对应的相机视角。通常,这些图像用于训练神经网络,让它学习如何从不同视角渲染场景。

  2. 神经网络模型

    NeRF使用一个深度神经网络来建模三维场景。这个网络的输入是空间中的位置(即三维坐标)和视角(即相机的方向),网络会输出该位置的颜色和密度(透明度)。这个过程本质上是通过神经网络来逼近场景的光学特性。

    神经网络的具体结构通常包括多个全连接层(MLP)。每个网络输出的颜色值是基于输入位置和视角信息进行计算的,而每个位置的密度决定了光线在该位置的穿透程度。

  3. 体积渲染(Volumetric Rendering)

    NeRF使用的是体积渲染方法,它可以通过沿着光线的路径来计算颜色和透明度。体积渲染的基本思想是:当光线通过一个包含物体的体积时,物体的密度会影响光的传播,最终改变图像的亮度和颜色。神经网络的任务是预测这些密度值和颜色值,从而计算出每一条光线的最终颜色。

    在渲染过程中,NeRF会将场景划分成若干小体素,模拟光线通过每个体素时的变化,计算出每个体素对最终图像的贡献。通过对所有体素的计算,NeRF能够渲染出图像中每个像素的最终颜色。

  4. 训练神经网络

    为了让神经网络能够准确地模拟场景的光学特性,NeRF需要使用输入的2D图像和相机视角进行训练。训练过程中,网络会调整其内部参数,以最小化渲染图像与真实图像之间的差异。

    训练过程通常是一个时间较长的过程,因为NeRF需要处理大量的三维坐标数据并进行细致的光线追踪。训练完成后,网络可以根据输入的新视角来渲染场景,生成新的图像。

HashNeRF优势

相较于 Vanilla NeRF 的收敛速度,HashNeRF-pytorch(左)与 NeRF-pytorch(右):

神经辐射场训练效果

仅仅训练了 5000 次迭代(大约 10 分钟,使用单个 1050Ti),你就开始看到清晰的椅子渲染效果了。😃

代码训练

从这里下载 nerf-synthetic 数据集:Google Drive(https://drive.google.com/drive/folders/1JDdLGDruGNXWnM1eqY1FNL9PlStjaKWi),百度云打包代码中已内置。

训练一个 chair HashNeRF 模型的命令:

python 复制代码
python run_nerf.py --config configs/chair.txt --finest_res 512 --log2_hashmap_size 19 --lrate 0.01 --lrate_decay 10

可直接在pycharm中运行run_nerf.py,训练过程示例:

  • 注意!若使用打包好的云盘代码,需先删除logs文件夹内已经训练好的文件。

代码库还额外支持:用于平滑嵌入的全变差损失(启用时使用 --tv-loss-weight);对光线权重的稀疏诱导损失(启用时使用 --sparse-loss-weight)。

parser参数说明

1、网络深度与宽度

python 复制代码
netdepth=8:定义粗网络的隐藏层数,对应论文中的8层MLP结构
netwidth=256:每层神经元的通道数,决定模型容量
netdepth_fine=8:精细网络深度(当N_importance>0时启用)

2、特征嵌入策略

python 复制代码
i_embed=1  # 1:哈希编码 0:标准位置编码 2:球面编码
i_embed_views=2  # 观察方向编码方案
multires=10  # 空间坐标频带数(2^10=1024个频段)
multires_views=4  # 视角方向编码频带

3、训练优化器

参数 默认值 作用机制 说明
lrate 1e-2 初始学习率 配合指数衰减使用
lrate_decay 10 每1000步衰减系数 复杂场景建议设为20
N_rand 32x32x4 每批光线数量 根据GPU显存调整
chunk 32K 并行处理光线数 显存不足时降至8K
precrop_frac 0.5 中心区域训练比例 加速初期收敛

4、 体渲染核心参数

渲染方程

python 复制代码
N_samples=64:粗采样点数(每条光线)
N_importance=128:精细采样点数(需配合精细网络)
perturb=1.0:加入随机抖动,打破网格伪影
raw_noise_std=0:噪声注入标准差(推荐1e-2应对过平滑)

5、数据集适配参数

python 复制代码
dataset_type='llff'  # 支持三种模式:
                    # 'llff':真实场景(默认forward-facing)
                    # 'blender':合成物体(需白背景)
                    # 'deepvoxels':特殊数据集

# LLFF数据集专属
factor=8            # 图像下采样因子(8→原始分辨率1/8)
no_ndc=True         # 非归一化设备坐标(全景场景启用)
spherify=True        # 360°球面场景标记

6、优化策略

实验数据:联合使用可使PSNR提升0.8dB

python 复制代码
tv-loss-weight=1e-6:全变分损失约束颜色场平滑度
sparse-loss-weight=1e-10:稀疏损失促进空间利用率

即时渲染加速

python 复制代码
render_factor=4   # 渲染分辨率降采样(4→1/4尺寸)
finest_res=512    # 哈希表最大分辨率
log2_hashmap_size=19  # 哈希表尺寸(2^19=524,288条目)

7、训练监控与调试

监控参数 频率 可视化工具 关键指标
i_print=100 每100步 控制台 损失值/PSNR
i_img=500 每500步 TensorBoard 渲染快照
i_testset=1000 每1000步 测试集目录 泛化能力
i_video=5000 每5000步 MP4视频 视角连贯性

结果示例

logs文件夹内每5k次生成一次结果:

NERF生成效果示例:

神经辐射场训练结果示例

相关推荐
杀生丸学AI1 个月前
【三维分割】Gaga:通过3D感知的 Memory Bank 分组任意高斯
aigc·三维重建·nerf·视觉大模型·3dgs·三维高斯溅射·分割一切sam
失舵之舟-2 个月前
【3DGS文献阅读】Splatter Image: Ultra-Fast Single-View 3D Reconstruction
3d·三维重建·nerf·3dgs·3d guassian·三维高斯溅射
windy贺蕾蕾3 个月前
blender如何使用nerf插件得到渲染好的二维图像和相机内外参数(blender数据集的构建)
算法·blender·nerf
PLUS_WAVE3 个月前
EG3D: Efficient Geometry-aware 3D Generative Adversarial Networks 学习笔记
笔记·学习·gan·nerf·head avatar·头像·3dvision
MorleyOlsen3 个月前
【经典论文阅读】NeRF(神经辐射场,neural radiance fields)
论文阅读·nerf
智驾机器人技术前线3 个月前
近期两篇NeRF/3DGS-based SLAM方案赏析:TS-SLAM and MBA-SLAM
3d·slam·nerf·3dgs
Yunni_root3 个月前
Ubuntu终端跑colmap实验记录——生成sparse和poses_bounds.npy
经验分享·ubuntu·计算机视觉·nerf·colmap·实验·bad-nerf
杀生丸学AI3 个月前
【三维重建】Semantic Gaussians:开放词汇的3DGS场景理解
3d·aigc·语义分割·三维重建·nerf·视觉大模型·空间智能
失舵之舟-3 个月前
3DGS与NeRF的区别
3d·重构·三维重建·nerf·3dgs·3d guassian