环境配置
https://www.youtube.com/watch?v=UXtuigy_wYc youtube复现视频
https://github.com/graphdeco-inria/gaussian-splatting 3DGS的github源码地址
https://dl.acm.org/doi/10.1145/3592433 论文地址
https://arxiv.org/abs/2308.04079
下载依赖和环境
视频老哥的github地址
https://github.com/jonstephens85/gaussian-splatting-Windows
下载git(跳过)
测试是否下载git –version
下载anaconda(跳过)
下载CUDA :nvcc –version测试版本
nvidia-smi确定电脑最高支持的CUDA版本 ,我的最高支持12.8
准备下载CUDA 11.8版本
安装vs2019
官方下载地址:https://visualstudio.microsoft.com/zh-hans/vs/older-downloads/
下载colmap
准备编译
打开anaconda prompt
D: 切换D盘
D:\user\desktop\workplace\3DGS\userdesktopworkplace3DGS
要将 Anaconda 创建的虚拟环境设置在 D 盘,可以按照以下步骤操作:
- 修改 Anaconda 配置
首先,需要修改 Anaconda 的配置,使其将环境创建在指定路径。
在 Anaconda Prompt 中执行以下命令:
conda config –add envs_dirs D:\Anaconda\envs
(如果需要,将 D:\Anaconda\envs 替换为你想要的路径) - 确保路径存在
确保你指定的路径已经存在。如果不存在,请手动创建该文件夹。 - 创建虚拟环境
现在你就可以创建虚拟环境,新的环境将被创建在 D 盘的指定路径下:
conda create –name env_name python=3.x - 检查环境位置
可以使用以下命令查看虚拟环境的位置:
conda info –envs
经过以上步骤后,你的虚拟环境将会在 D 盘创建。
conda create -n gaussian_splatting python=3.7
conda activate gaussian_splatting
conda install -c conda-forge vs2019_win-64
pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchaudio==0.13.1 –extra-index-url https://download.pytorch.org/whl/cu117
pip install submodules/diff-gaussian-rasterization
pip install submodules/simple-knn
pip install submodules/fused-ssim
训练
3dgs的运行训练
下述所有命令都是在终端里运行的,运行时保持是从gaussian-splatting目录下开始输入的。
省流版本:conda activate gaussian_splattingd:cd D:\sys\Desktop\Workplace\3DGS新的路径
训练:python train.py -s data_train -m data_train/output (参数为输出地址)python render.py -m data_train/output
把train文件夹的method复制到test文件夹python metrics.py -m data_train/output
1.视频截取帧
这里可以用自己手机拍摄的一段视频,一两分钟即可,可以参考一下作者的训练时间,作者用自己的笔记本(4060 8G),大概训练了两个小时左右,跑完了所有的迭代。
在gaussian-splatting目录下新建一个data文件夹,将你拍摄的视频移动到该data文件夹下,并将你的视频改名为input,后缀.mp4不用改。然后在data文件夹里再建一个与视频同名的文件夹,名字也是input。然后就可以输入命令啦(终端里从gaussian-splatting/data目录下开始输入)
cd data
ffmpeg -i input.mp4 -vf "setpts=0.2*PTS" input\input_%04d.jpg #推荐运行这个指令
ffmpeg -i input.mp4 -vf "setpts=0.2*PTS,fps=1" input\input_%04d.jpg #如果需要调整抽帧频率可以参考这个指令。选择一个运行即可
这里简单的说一下各个参数的含义。
setpts=0.2*PTS 将视频播放速度加快到原来的 5 倍。这意味着原视频的每秒帧数增加到 5 倍。
如果原始视频是 30 FPS,加速后的视频将以 150 FPS 播放。
尽管视频播放速度加快了,ffmpeg fps=1 会以每秒一帧的频率提取图片。
这样就可以把你的视频截取为帧并保存在input文件夹里,在input文件夹里应该可以看到许多张照片。
2.产生点云
在终端gaussian-splatting目录下输入
cd ..
python convert.py -s data
这个就是利用安装的colmap产生点云,会花费一些时间,等待完成即可。
3.查看点云
终端里输入
colmap
调出来colmap后,选择file->import model
然后选择gaussian-splatting/data/sparse/0文件夹,选择确定,即可打开生成的点云,遇到弹窗×掉即可。可以看到生成的点云还有相机路径。
4.开始训练
同样,在终端里gaussian-splatting目录下,输入
python train.py -s data -m data/output (参数为输出地址)
python train.py -s data -m data/images
成功开始会出现如下图所示
然后耐心等待训练完成以后即可。
5.查看结果
同样,在终端里gaussian-splatting目录下,输入
.\viewers\bin\SIBR_gaussianViewer_app -m data/output
即可打开viewer窗口,可以把你的场景拖大,下面是一些快捷按键
w uio
asd jkl
就是可以控制视角的变化,大家自己按一下就知道是干啥的了,这里就不一一列举对应的功能了(作者已经累了),注意切换输入法为英文输入。
至此,就全部结束啦,完结撒花!
1 . convert.py
将input数据集转换成为点云
通过sfm算法将输入的图片集转换成点云,这种方式的具体流程如下:
- 特征提取:从输入的图像集中,对每一张图像提取特征点及其描述子,常用的特征提取算法有 SIFT、SURF、ORB 等。
- 全局特征匹配:在所有图像的特征点之间进行匹配,找出不同图像中表示同一物理点的特征点对。由于是全局匹配,可能会处理大量的特征点对,计算量较大。
- 相机位姿估计:根据匹配的特征点对,使用诸如对极几何、PnP 等算法来估计相机的相对位姿。
- 三角测量:利用已知的相机位姿和匹配的特征点,通过三角测量计算出三维点的坐标,从而生成点云。
- 全局优化:使用束调整(Bundle Adjustment)等方法对相机位姿和三维点的坐标进行全局优化,提高点云的精度。
SfM 侧重于对静态图像集进行全局处理,通过全局优化来生成高精度的点云,SfM相比ORB方法 更侧重于离线的高精度三维重建.
渲染辐射场的几种方法建立了最近的数据集。革命性地合成了用多张照片或视频捕获的场景。然而,实
现高视觉质量仍然需要训练和渲染成本高昂的神经网络,而最近更快的方法不可避免地要牺牲速度来换
取质量。对于无界和完整的场景(而不是孤立的对象)和1080p分辨率的渲染,目前没有一种方法可以实现
实时显示速率。我们介绍了三个关键要素,使我们能够在保持有竞争力的训练时间的同时实现最先进的
视觉质量,并且重要的是允许在1080p分辨率下实现高质量的实时(≥30 fps)新视图合成。首先,从相机
校准过程中产生的稀疏点开始,我们用3D高斯分布表示场景,该分布保留了用于场景优化的连续体辐射
场的理想属性,同时避免了在空白空间中不必要的计算;其次,我们对3D高斯分布进行交错优化/密度控
制,特别是优化各向异性协方差以实现场景的准确表示;第三,我们开发了一种支持各向异性喷溅的快速
可视性感知渲染算法,既加速了训练,又允许实时渲染。我们展示了最先进的视觉质量和实时性
3dgs流程
3DGS流程:
(1)通过colmap等工具从多视角图像获取SfM点云(SfM是一种三维重建算法,通过两个或多个场景/图片恢复相机位姿,并重建三维坐标点),对 SfM 点云进行了初始化。
(2)点云中的每一个点代表着一个三维的高斯分布,除了点的位置(均值)外,还有协方差、不透明度、颜色(球谐函数)–3D 高斯球云。
(3)将这些椭球体沿着特定角度投影到对应位姿所在平面(Splatting)。一个椭球体投影到平面会得到一个椭圆;然后通过计算待求解像素和椭圆中心的距离,我们得到不透明度(离的近,说明越不透明);每个椭球又代表各自的颜色,进行alpha composting来合成颜色,然后快速的对所有像素做“可微光栅化”,渲染得到图像。
(4)得到渲染图像Image后,再与gt图像比较,得到损失loss,并沿蓝色箭头反向传播,随机梯度下降;向下送入自适应密度控制中(增密或修剪),更新点云优化。
代码运行流程
1.Running
python train.py -s
示例:
python train.py -s data/360_extra_scenes/treehill
运行完在output下得到相应的文件夹output/treehill,
将得到的结果路径添加至SIBR_viewer.py(model_path = r’D:\gaussian-splatting\output\treehill’),运行即可获得可视化。
densify_and_prune操作会改变高斯数量。结合在一起,允许模型根据当前两个的训练状态动态地调整高斯的数量,从而实现更好的表示能力和计算效率。因此,在这个过程中,高斯的数量会变化,所以需要在执行后打印出当前的高斯数量。在训练的时候添加高斯数量打印:
print(f”Iteration {iteration}: Number of Gaussians after densification and pruning: {gaussians.get_xyz.shape[0]}”)
2. Evaluation
python train.py -s
python render.py -m
python metrics.py -m
训练模型->渲染图像->计算指标
示例:Evaluation运行,输入命令行(python train.py -s + 数据集的路径)
python train.py -s data/360_extra_scenes/treehill –eval
python render.py -m output/treehill
python metrics.py -m output/treehill
2. Processing your own Scenes
按照README.me进行,选择的mill19/building-pixsfm进行简单测试
图像目录结构:
1 | <location> |
然后运行: python convert.py -s data/mill19/building-pixsfm
两句代码优化3DGS显存问题
做实验的时候发现,对于同一个场景,图片越多显存占用越大。但是训练的时候是一张图片做一次梯度下降,说明batch_size一直是1。那数据集变大,batch_size不变的情况下,显存占用却变大了,这明显很不合理。当训练的图片比较多的时候,显存就不够了。
图片越多,显存占用越大,这就暗示了3DGS源码里一定是训练前预先将所有的图片都加载显存中的。事实也确实如此,在训练前的预处理中,为每张图片都构造了一个对应的Camera对象,Camera的初始化函数中就将图片加载到了显存中,如下。
源码scene/cameras.py中39行,修改前
self.original_image = image.clamp(0.0, 1.0).to(self.data_device)
修改后
self.original_image = image.clamp(0.0, 1.0)
这优化很简单,不要提前载入显存就好了,直接把“.to(self.data_device)”删掉。训练的时候,具体训练哪张图片,载入哪张图片就好了。这个在3DGS源码中,已经做了,如下。经过所述的代码修改后,确实显存减少了,但是训练速度变慢了。因为相比修改前,多出来的耗时在每次训练迭代中都有一次图片加载到显存中的操作。在cuda中将数据从内存载入显存是可以异步进行的,pytorch也提供了接口,所以对代码做出以下修改。
源码train.py中90行,修改前
gt_image = viewpoint_cam.original_image.cuda()
修改后,需移动到render_pkg = render(…)之前
gt_image = viewpoint_cam.original_image.cuda(non_blocking=True)
不过仅仅只是将载入方式设置为non_blocking还不够,因为可能在要使用gt_image之前其还没有完成载入显存的操作,此时也会发生阻塞。所以需要将这句代码往前放,可以放到“render_pkg = render(viewpoint_cam, gaussians, pipe, bg)”这句之前。这样就几乎不会影响训练速度。