ubuntu22.04复现3DGS,包含双系统、cuda、conda、colmap的安装
本人在复现3dgs的路上可谓是一番波折,踩了许多坑,但所谓关关难过关关过,最终还是实现了。
系统环境:
ubuntu22.04
cuda11.8
pytorch2.6.0
colmap3.8 (必须是这个版本)
一、配置windows和ubuntu双系统
本人一开始使用24.04,抱着用最新系统试一试的态度去做,但是遇到一大堆问题,最后心态崩溃回归ubuntu22.04的怀抱。
双系统配备视频,内容完备。
【Windows 和 Ubuntu 双系统的安装和卸载】
推荐两个本人喜欢的更改,让ubuntu界面更加舒服:
1、ubuntu新窗口居中显示,可以让终端、文件夹什么的第一次打开时在屏幕里居中显示
解决:如何使Ubuntu中新窗口显示在屏幕中央?_ubantu打开控制台默认在屏幕中心-CSDN博客
2、顶部状态栏隐藏,让屏幕更大
Ubuntu22.04版本侧边栏和顶部栏隐藏与其他版本不同_ubuntu顶部菜单栏-CSDN博客
二、安装nvidia驱动、cuda、conda、pytorch、colmap
1、安装nvidia驱动以及更换驱动方式
检查是否安装了nvidia驱动,终端输入:
nvidia-smi
出现此界面则表示已安装驱动,其中575.64.03即为驱动的版本,CUDA Version:12.9代表该驱动下能兼容的最高版本的cuda,表示本人cuda安装的最高版本不要超过12.9。
若输入nvidia-smi未出现此界面,则需为其安装nvidia驱动,输入下行命令会自动安装系统所推荐的驱动,随后重启电脑,重新输入nvidia-smi就可看到GPU详细信息。
sudo ubuntu-drivers autoinstallsudo reboot #重启电脑nvidia-smi
更换显卡驱动的方式:打开,选择附加驱动,会看到:
选择想要安装的驱动点击右下角应用更改,随后重启电脑即可。
2、安装cuda以及多版本cuda切换
2.1、安装cuda11.8
3dgs推荐安装cuda11.8,各版本cuda的下载链接如下:
CUDA Toolkit Archive | NVIDIA Developer
找到cuda toolkit11.8.0,选择适合自己系统的版本安装即可,随后配置环境变量:
sudo gedit ~/.bashrcexport PATH=\"/usr/local/cuda-11.8/bin:$PATH\"export LD_LIBRARY_PATH=\"/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH\"export CUDA_HOME=/usr/local/cuda# 更新系统环境source ~/.bashrcsudo ldconfig# 验证是否成功nvcc -V
输出以下内容即为安装成功:
2.2多版本cuda切换
相信许多人和我一样,事先已经安装过别的版本的cuda了,我在安装cuda11.8之前就已安装了cuda12.4deb版本,但是不要紧,只需简单的操作即可。在已有cuda12.4deb的基础上,在选择下载cuda11.8时选择runfile版本,按上述步骤安装。
在cuda安装过程中需要注意取消安装显卡驱动
在安装完cuda11.8runfile版本后,在.bashrc文件里修改环境变量即可切换cuda版本,同样的方式,要切换回cuda12.4版本也只需改环境变量即可。
sudo gedit ~/.bashrcexport PATH=\"/usr/local/cuda-XX.X/bin:$PATH\" #cuda-XX.X为需要使用的版本export LD_LIBRARY_PATH=\"/usr/local/cuda-XX.X/lib64:$LD_LIBRARY_PATH\" export CUDA_HOME=/usr/local/cuda# 更新系统环境source ~/.bashrcsudo ldconfig# 验证是否成功nvcc -V
更多细节看原链接:ubuntu22.04多版本安装cuda及快速切换(cuda11.1和11.8)_ubuntu22.04安装cuda11.1-CSDN博客
3、安装conda
# 下载 Miniconda 安装脚本wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh # orcurl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh# 运行安装脚本bash Miniconda3-latest-Linux-x86_64.sh
按住enter直至出现“yes or no”,输入yes,然后会提示是否指定安装路径,默认路径的话直接enter即可,最后一步会出现下面画面提示初始化conda,输入 yes 进行初始化。
随后配置环境变量,并对conda进行测试:
# 激活 Conda 环境source ~/.bashrc# 测试conda --version
最后输出conda的版本信息即为安装成功。
conda安装参考链接:Ubuntu 24.04安装nvdia显卡驱动、CUDA、Miniconda和Pytorch,及.venv\\Lib\\site-packages\\torch\\lib\\shm.dll错误_ubuntu24.04安装显卡驱动-CSDN博客
conda基本命令操作:conda常用命令:安装,更新,创建,激活,关闭,查看,卸载,删除,清理,重命名,换源,问题_conda activate-CSDN博客
4、安装pytorch
pytorch官网安装地址:Previous PyTorch Versions
选择适合自己cuda的版本安装,查看自己cuda版本:
nvcc -V#ornvcc --version
以我的cuda11.8为例,则选择以下版本:
最后可对cuda、pytorch、GPU版本等等进行检验,创建 .py 文件:
import torch# 检查 PyTorch 版本print(torch.__version__) # 检查 CUDA 是否可用print(torch.cuda.is_available()) # 检查 cuDNN 版本print(torch.backends.cudnn.version()) # 检查当前 GPU 设备print(torch.cuda.current_device()) # 检查 GPU 名称print(torch.cuda.get_device_name(0))
执行python文件,出现如下画面即为安装成功:
pytorch安装参考链接:难道他真的是装环境的天才(双系统ubuntu24.04+cuda+pytorch+cudnn安装)_ubuntu24.04 安装cuda12.1-CSDN博客
5、安装colmap
5.1检查colmap版本确定是否需要卸载重装
必须安装colmap3.8版本!!必须安装colmap3.8版本!!若安装过colmap,先查看colmap版本是否为3.8,输入下行可以看到colmap版本信息:
colmap help
若不是3.8版本则需要先对其进行卸载:(根据安装方式选择卸载方法)
(1)通过 apt 安装的卸载
# 移除主程序sudo apt remove --purge colmap# 移除依赖项(谨慎使用,会移除可能被其他软件使用的包)sudo apt autoremove --purge# 清理配置文件rm -rf ~/.config/colmap
(2)通过源码编译安装的卸载
在colmap文件夹里找到 CMakeUninstall.cmake 这个文件所在的目录,一般在 /colmap/build 里或者在 /colmap 里,随后执行卸载:
# 定位编译目录(假设在 ~/colmap/build)cd ~/colmap/build# 执行卸载sudo make uninstall# 彻底删除残留sudo rm -rf /usr/local/lib/libcolmap*sudo rm -rf /usr/local/include/colmapsudo rm -rf /usr/local/bin/colmap
(3)通过conda安装的卸载
conda remove --name your_env_name colmap# 或全局卸载conda remove colmap
通过以上三个方法卸载colmap后,还需进行深度清理:
#1. 删除用户配置文件rm -rf ~/.colmaprm -rf ~/.config/colmaprm -rf ~/.local/share/colmap#2. 清除系统级残留# 库文件sudo find /usr -name \"*colmap*\" -exec rm -rf {} \\;# 头文件sudo rm -rf /usr/local/include/colmap# 二进制文件sudo rm -f /usr/local/bin/colmap#3. 清除 Python 绑定(如果存在)pip uninstall colmappip uninstall pycolmap#4. 检验卸载是否彻底# 检查可执行文件which colmap # 应无输出# 检查库文件ldconfig -p | grep colmap # 应无输出
5.2安装colmap3.8
在卸载完colmap后进行colmap3.8的下载安装,各版本colmap下载链接:
https://github.com/colmap/colmap/releases
colmap3.8下载链接:
https://github.com/colmap/colmap/archive/refs/tags/3.8.zip
首先安装依赖:
sudo apt-get install \\ git \\ cmake \\ ninja-build \\ build-essential \\ libboost-program-options-dev \\ libboost-filesystem-dev \\ libboost-graph-dev \\ libboost-system-dev \\ libeigen3-dev \\ libflann-dev \\ libfreeimage-dev \\ libmetis-dev \\ libgoogle-glog-dev \\ libgtest-dev \\ libgmock-dev \\ libsqlite3-dev \\ libglew-dev \\ qtbase5-dev \\ libqt5opengl5-dev \\ libcgal-dev \\ libceres-dev
安装好以来后进行colmap安装,注意CMAKE_CUDA_ARCHITECTURES
代表的是显卡硬件架构编号, rtx2080ti 对应75, rtx4060ti 对应89,各版本如下图所示:
cd colmap-3.8mkdir buildcd buildcmake .. -GNinja -DCMAKE_CUDA_ARCHITECTURES=89ninjasudo ninja install
如果在编译途中出现了任何问题,可以删除build文件夹清除缓存,再重复上述步骤。
最后测试colmap是否安装成功,输入命令出现colmap的界面即为安装成功:
colmap gui
参考链接:[论文][环境]3DGS+Colmap环境搭建_WSL2_Ubuntu22.04_3dgs colmap-CSDN博客
三、复现3DGS
1、配置虚拟环境
3DGS源码链接:https://github.com/graphdeco-inria/gaussian-splatting
获取源码,一定要下全--recursive:
git clone https://github.com/graphdeco-inria/gaussian-splatting --recursive
首先创建虚拟环境,有两种方法:
(1)根据源码方式为:
#创建虚拟环境conda env create --file environment.yml#激活虚拟环境conda activate gaussian_splatting
因为conda网络的连接很慢,下载速度很慢,随时可能断开,本人用这个方式死活创建不了虚拟环境,不推荐使用此方式,用第二种分体安装方法更为实用。
(2)分体安装配置虚拟环境
#创建虚拟环境conda create -n gs python=3.8#激活虚拟环境conda activate gs#安装pytorch,可用上述对pytorch的检验方法在虚拟环境中对pytorch进行检验pip install torch==2.0.0 torchvision==0.15.1 torchaudio==2.0.1 --index-url https://download.pytorch.org/whl/cu118 #安装其他依赖sudo apt install -y libglew-dev libassimp-dev libboost-all-dev libgtk-3-dev libopencv-dev libglfw3-dev libavdevice-dev libavcodec-dev libeigen3-dev libxxf86vm-devpip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python plyfile tqdm joblib matplotlib#进入源码文件cd gaussian-splattingpip install submodules/diff-gaussian-rasterizationpip install submodules/simple-knnpip install submodules/fused-ssim
均安装成功后即虚拟环境配置即为成功,可以进行复现了。
3DGS虚拟环境配置参考链接:WIN11安装Ubuntu22.04双系统,驱动cuda,配置3D GS_nvidia corporation device 2860 (rev a1)-CSDN博客
2、3DGS训练模型输出成果
首先准备好训练视频(10秒左右录一个物体即可),在gaussian-splatting文件夹下创建data,再在data文件夹下创建一个文件夹放置你的视频:(文件夹Chomper即为我的视频存放路径)
#激活虚拟环境conda activate gs#进入视频存放文件夹cd gaussian-splatting/data/Chomper/#使用ffmpeg截取视频帧为图片,在Chomper目录下创建input目录,将截取好的图片放到该目录下mkdir inputffmpeg -i Chomper.mp4 -vf \"setpts=0.2*PTS\" input/input_%4d.jpg#返回到gaussian-splatting文件夹下,使用源码中的convert.py生成点云,过程中会调用colmapcd gaussian-splatting/python convert.py -s data/Chomper/#开始训练,训练完成后,data文件夹下生成一个output文件夹,里面存放着训练结果python train.py -s data/Chomper -m data/Chomper/output
训练完成后还需对训练结果进行可视化,使用gaussian-splatting文件夹下的SIBR_viewers进行可视化:
#先配置SIBR_viewers的环境cd SIBR_viewerscmake -Bbuild . -DCMAKE_BUILD_TYPE=Release # add -G Ninja to build fastercmake --build build -j24 --target install#最后找到SIBR_viewers的启动程序位置运行SIBR_viewers./gaussian-splatting/SIBR_viewers/install/bin/SIBR_gaussianViewer_app -m ~/gaussian-splatting/data/Chomper/output/
使用SIBR_viewers可视化参考链接:Ubuntu20.04 3DGS复现全流程-CSDN博客 3D Gaussian Splatting复现-CSDN博客
结果如下:
将下面代码保存为 .html 文件格式后打开可实现滑动来对比效果:
自适应比例图片对比滑动组件 * { margin: 0; padding: 0; box-sizing: border-box; font-family: \'Segoe UI\', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #0f2027, #203a43, #2c5364); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 30px 20px; color: white; overflow-x: hidden; } .comparison-container { position: relative; width: 100%; max-width: 700px; /* 最大宽度 */ background: #000; box-shadow: 0 15px 50px rgba(0, 0, 0, 0.5); } .image-wrapper { position: relative; width: 100%; height: 0; padding-bottom: 56.25%; /* 默认16:9比例,可根据图片的实际比例调整 */ } .comparison-image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: block; object-fit: contain; } .twenty-before { clip: rect(0px, 50%, 100%, 0px); z-index: 2; } .twenty-after { clip: rect(0px, 100%, 100%, 50%); } .twenty-handle { position: absolute; left: 50%; top: 0; bottom: 0; width: 4px; background: white; cursor: ew-resize; z-index: 3; transform: translateX(-50%); box-shadow: 0 0 20px rgba(0, 0, 0, 0.8); } .twenty-handle::before { content: \"\"; position: absolute; width: 50px; height: 50px; border-radius: 50%; background: white; top: 50%; left: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 15px rgba(0, 0, 0, 0.7); }
document.addEventListener(\'DOMContentLoaded\', function() { const container = document.getElementById(\'image-wrapper\'); const beforeImg = document.getElementById(\'before-image\'); const afterImg = document.getElementById(\'after-image\'); const handle = document.getElementById(\'handle\'); let isDragging = false; let startX, startLeft; // 图片加载后初始化组件 function initComponent() { // 设置容器比例 setContainerAspectRatio(beforeImg); setContainerAspectRatio(afterImg); // 初始化滑块位置 initSlider(); } // 根据图片宽高设置容器的比例 function setContainerAspectRatio(image) { const imgWidth = image.naturalWidth; const imgHeight = image.naturalHeight; const aspectRatio = imgHeight / imgWidth; // 设置容器的高度比例 container.style.paddingBottom = (aspectRatio * 100) + \"%\"; } // 初始化滑块位置 function initSlider() { const containerWidth = container.offsetWidth; const position = containerWidth / 2; updateClip(position); handle.style.left = position + \'px\'; } // 更新图片裁剪区域 function updateClip(pos) { const containerHeight = container.offsetHeight; beforeImg.style.clip = `rect(0px, ${pos}px, ${containerHeight}px, 0px)`; afterImg.style.clip = `rect(0px, ${container.offsetWidth}px, ${containerHeight}px, ${pos}px)`; } // 添加鼠标事件 handle.addEventListener(\'mousedown\', startDrag); // 添加触摸事件 handle.addEventListener(\'touchstart\', startDrag); // 容器点击事件 container.addEventListener(\'click\', function(e) { if (isDragging) return; const rect = container.getBoundingClientRect(); const position = e.clientX - rect.left; updateClip(position); handle.style.left = position + \'px\'; }); // 开始拖动 function startDrag(e) { e.preventDefault(); isDragging = true; const startX = e.clientX || e.touches[0].clientX; const startLeft = parseFloat(handle.style.left); function onDrag(e) { const currentX = e.clientX || e.touches[0].clientX; const rect = container.getBoundingClientRect(); let newPosition = startLeft + (currentX - startX); // 限制位置在容器范围内 newPosition = Math.max(0, Math.min(newPosition, container.offsetWidth)); updateClip(newPosition); handle.style.left = newPosition + \'px\'; } function stopDrag() { document.removeEventListener(\'mousemove\', onDrag); document.removeEventListener(\'mouseup\', stopDrag); document.removeEventListener(\'touchmove\', onDrag); document.removeEventListener(\'touchend\', stopDrag); isDragging = false; } document.addEventListener(\'mousemove\', onDrag); document.addEventListener(\'mouseup\', stopDrag); document.addEventListener(\'touchmove\', onDrag, { passive: false }); document.addEventListener(\'touchend\', stopDrag); } // 窗口大小变化时重新计算 window.addEventListener(\'resize\', function() { initSlider(); }); // 图片加载后初始化 beforeImg.addEventListener(\'load\', function() { initComponent(); }); afterImg.addEventListener(\'load\', function() { initComponent(); }); // 如果图片已经加载完成 if (beforeImg.complete && afterImg.complete) { initComponent(); } });