背景
今年以来以chatgpt为代表的大模型的惊艳表现彻底点燃了AICG这个领域的。各类gpt,各种AI作图产品如雨后春笋般出现。每个成功产品的背后都是一个个精妙的算法,本篇文章给大家详细介绍下如何使用一个手机拍摄若干张同一场景的照片,然后合成新视角,生成视频的流程与代码。本文使用的技术是NeRF(Neural Radiance Fields),它是2020年以来出现的一种基于深度学习的3D重建方法,它通过学习场景的光线传输和辐射传递,能够生成高质量的场景渲染图像和3D模型。关于它的原理与文献,我在最后有一个参考列表供大家学习。本文主要从代码使用以及环境搭建的新角度介绍它。
环境搭建
environment.yml修改
本文使用的硬件环境是 GPU RTX3090,操作系统是windows 10.采用的软件是开源的NeRF实现(https://github.com/cjw531/nerf_tf2)。由于RTX 3090需要CUDA 11.0及以上版本的支持,TensorFlow-gpu 需要2.4.0以及以上的支持,所以我们没有选择官方的https://github.com/bmild/nerf,因为bmild这个的环境使用的tensorflow-gpu==1.15,版本太久了。跑起来会有下面的问题https://github.com/bmild/nerf/issues/174#issue-1553410900,我在这个tt中也回复指出了需要升级到2.8。但是即便是使用https://github.com/cjw531/nerf_tf2,它的环境也是有点问题。首先由于它连接的国外的conda的channel,所以速度很慢。其次它的环境使用的是tensorflow==2.8没有指明tensorflow-gpu的版本。针对这两个问题。我们对environment.yml进行了修改。
# To run: conda env create -f environment.yml
name: nerf_tf2
channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
- conda-forge
dependencies:
- python=3.7
- pip
- cudatoolkit=11.0
- cudnn=8.0
- numpy
- matplotlib
- imageio
- imageio-ffmpeg
- configargparse
- ipywidgets
- tqdm
- pip:
- tensorflow==2.8
- tensorflow-gpu==2.8
- protobuf==3.19.0
- -i https://pypi.tuna.tsinghua.edu.cn/simple
启动conda环境
打开cmd,然后输入下面的命令。
conda env create -f environment.yml
将nerf_tf2加入到jupyter中,这样使用jupyter能很方便的查看系统的运行结果。
// 安装ipykernel
conda install ipykernel
//是该conda环境在jupyter中显示
python -m ipykernel install --user --name 环境名称 --python -m ipykernel install --user --name 环境名称 --display-name "jupyter中显示名称"display-name "jupyter中显示名称"
//切换到项目目录
cd 到项目目录
//激活conda环境
activate nerf_tf2
//在cmd启动jupyter
jupyter notebook
至此conda环境以及jupyter准备就绪。
数据准备
- 下载并安装colmap,我的环境是windows(https://demuc.de/colmap/#download)
- 使用https://github.com/fyusion/llff提供的imgs2poses.py实现自己相机拍摄的图片的相机内外参数的获取,比如我们的拍摄了10张图片,它们放置的目录位置很讲究,D:/LanJing/AI/LLFF/data/images,也就是说一定要放在images子目录下面。而你传入的参数是python imgs2poses.py D:/LanJing/AI/LLFF/data。因为它的代码里面的images_path的写法是这个样子(https://github.com/Fyusion/LLFF/blob/master/llff/poses/colmap_wrapper.py#L28)
feature_extractor_args = [
'colmap', 'feature_extractor',
'--database_path', os.path.join(basedir, 'database.db'),
'--image_path', os.path.join(basedir, 'images'),
'--ImageReader.single_camera', '1',
# '--SiftExtraction.use_gpu', '0',
]
运行完imgs2poses.py文件后,生成了sparse目录、colmap_out.txt、database.db、poses_bounds.npy,然后我们在nerf_tf2项目下创建新目录data/nerf_llff_data/ll,将上面的sparse目录以及poses_bounds.npy复制到这个目录下。最后我们再配置个新文件config_ll.txt。至此我们的数据准备工作完成了。
expname = ll_test
basedir = ./logs
datadir = ./data/nerf_llff_data/ll
dataset_type = llff
factor = 8
llffhold = 8
N_rand = 1024
N_samples = 64
N_importance = 64
use_viewdirs = True
raw_noise_std = 1e0
训练
将开源软件迁移到windows平台上。
由于此开源软件主要是支持mac和linux,它无法在windows运行,需要对load_llff.py的修改。
运行300000次批量训练。
activate nerf_tf2
python run_nerf.py --config config_ll.txt
测试
效果
由于我们使用的输入图片有些少,只有10张,所以运行出来的效果不是很好,但是整体的流程是一样。tips:官方的代码里面使用的一半都是30,甚至100张图片。
我们的效果
官方效果
参考资料
https://zhuanlan.zhihu.com/p/554093703。
https://arxiv.org/pdf/2003.08934.pdf。
https://zhuanlan.zhihu.com/p/593204605。
https://inst.eecs.berkeley.edu/~cs194-26/fa22/Lectures/nerf_lecture1.pdf。