一、MVSNet的学习
1、1定义以及流程
MVS是一种从具有一定重叠度的多视图视角中恢复场景的稠密结构的技术,是在2018年提出的一种基于深度学习的端到端深度估计框架,是比较早期且较为完整的三维重建深度学习框架。
网络首先提取图像的深度特征,然后通过可微分投影变换构造3D的代价体,再通过正则化输出一个3D的概率体,再通过soft argMin层,沿深度方向求取深度期望,获得参考影像的深度图。
深度特征提取
首先有一张参考图像(r img)和任意张源图像(r img),这些图像利用一个八层的二维卷积神经网络提取立体像对的深度特征Fi,输出的特征图是N个图片对应的N个32通道的特征图。
构造匹配代价
构造一张图片的深度图,首先需要把s img 这些图片的视角转换为r img的视角,经过单应性变换(Homography)之后,把s img的特征图,映射到r img的特征图对应的锥形立体空间之后,将所有特征地图扭曲成参考相机的不同前平行平面,形成N个特征体,由于深度不一样,形成上面红框的锥形(长宽不一样)。
代价累计,构造代价体
MVSNet的代价累积通过构造代价体实现的。代价体是一个由长、宽与参考影像长宽一样的代价图在深度方向连接而成的三维结构,在深度维度,每一个单位表示一个深度值。其中,某一深度的代价图上面的像素表示参考影像同样的像素在相同深度处,与候选集影像的匹配代价。
深度估计
有代价体得到概率体,通过神经网络训练学习,输入代价体和对应的深度图真值,利用下图方法回归每一个像素在此深度的概率,得到一个表示r img 每个影响延深度方向的概率体。
代价体规则化,得到概率体
应用多尺度3D CNN进行成本-体积正则化,它使用编码器-解码器结构,最后,沿着深度方向应用softmax操作进行概率归一化。最后得到的概率体就是在每个深度下,每个像素的可能性大小。
得到深度图
计算深度的数学期望作为初始深度图D的结果,即Soft Argmin
Depth Map Refinement
由于得到的初始深度图在物体边缘还是不够精细,因此使用原始图像信息来进行细化。这里是将深度图与原始图像串连成一个四通道的输入,经过神经网络得到深度残差,然后加到之前的深度图上从而得到最终的深度图。
关于求解代价体和单应性变换,写了一些笔记
下图时论文中公式出现了错误,以及正确公式的一个详细书写
二、运行CasMVSNet
1、环境配置
一开始本来想运行MVSNet的pytorch实现,但是遇到了一些问题,所以先进性CasMVSNet的运行。
https://github.com/alibaba/cascade-stereo/tree/master/CasMVSNet
选择的是Miniconda conda3 Cuda10.0
点击JupyterLab进入系统,首先需要激活anconda,以及根据实验配置虚拟环境,Python3.6,这里参照的是以下文章
https://github.com/Wang-Ruiyang/DeepLeaning/tree/master/Install
最后可以得到如下python3.6的运行环境
2、安装配置
基本操作和虚拟机Linux系统一样,这里下载pytorch1.0.1版本,命令按照官网给出的命令
https://pytorch.org/get-started/previous-versions/
conda install pytorch==1.0.1 torchvision==0.2.2 cudatoolkit=10.0 -c pytorch
接着cd到该实验目录下,运行如下命令
pip install -r requirements.txt
安装实验所需要的包
3、运行测试
这里不进行训练了,dtu数据集比较大,直接下载预训练好的模型,运行test.sh去测试数据,也要下载dut.zip测试数据集,解压放在文件夹中
下载之后我放在了 我新建的checkpoint文件夹中
这里第一行是我放的dtu路径,dtu就在CasMVSNet文件夹下,可以直接这样写相对路径,第二行不需要改动,第三行是预训练的模型位置,第四行是运行test.py的命令,后面是几个参数,这些已经设定好的也不需要改动,batch_size:表示单次传递给程序用以训练的参数个数
这里可以在test.py里看参数设置
直接运行,设置输出路径为outputs
export save_results_dir="./outputs"
./test.sh $CKPT_FILE --outdir $save_results_dir --interval_scale 1.06
运行时间很长,得到如下输出
可以使用meshlab打开一个ply文件
可以得到点云模型。
4、使用colmap的数据
colmap的安装参考如下链接
https://zhuanlan.zhihu.com/p/361936953
直接从本机下载开始操作。
我这里下载的时候,一开始也是按照git命令进行获取,但是出现无法获取资源或者超时的问题,而且版本都是最新的版本,可能会有问题,所以我直接下载的压缩包到系统中进行解压。
colmap是3.6版本,ceres-solver的2.0.0版本。
这里通过命令行进行稀疏重建,在colmap目录下新建image文件,存放图片,在该目录下进行命令行操作。
colmap稀疏重建的过程参考如下链接
https://zhuanlan.zhihu.com/p/362701018
这篇文章进行最后一步融合时,命令有一个小问题
1、Colmap进行重建
1、特征提取
colmap feature_extractor \
--database_path ./database.db \
--image_path ./images
输出:database.db中保存特征点
2、特征点匹配
colmap exhaustive_matcher \
--database_path ./database.db
3、稀疏重建
mkdir sparse
colmap mapper \
--database_path ./database.db \
--image_path ./images \
--output_path ./sparse
输出:sparse文件夹
cameras.bin -----> 相机内参
images.bin -----> 相机位姿
points3D.bin -----> 稀疏3D点
4、图像去畸变
mkdir dense
colmap image_undistorter \
--image_path ./images \
--input_path ./sparse/0 \
--output_path ./dense \
--output_type COLMAP \
5、稠密重建
colmap patch_match_stereo \
--workspace_path ./dense \
--workspace_format COLMAP \
--PatchMatchStereo.geom_consistency true
输出:dense/stereo文件夹,为每张图像估计depth_map和normal_map
6. 融合
colmap stereo_fusion \
--workspace_path ./dense \
--workspace_format COLMAP \
--input_type geometric \
--output_path ./dense/result.ply
输出:result.ply点云模型文件
接着主要使用稀疏重建得到的内容作为CasMVSNet的输入进行重建
2、输入Colmap数据
1、导出相机参数和中间数据
按照如下命令转换为txt文件,路径是dense/sparse
camera.txt是保存相机内参数的文件
images.txt是保存图片外参数和图片二维特征与三维空间点对应信息的文件
points3D.txt是保存三维空间点在世界坐标系下坐标、RGB值以及在各个影像上的轨迹(track)
2、作为输入
主要运行colmap2mvsnet.py,将colmap SfM结果转换为CasMVSNet输入
这里的路径我使用的是autodl里的绝对路径
python colmap2mvsnet.py --dense_folder /root/autodl-tmp/colmap/dense --save_folder /root/autodl-tmp/CasMVSNet/casmvsnet
得到如下文件
运行test.sh 我这里都是用的是相对路径,因为使用绝对路径时总是出现找不到该路径,当时没有解决这个问题,后续再看怎么解决。
最后将这个输出casmvsnet.ply和通过colmap稠密重建得到的ply文件都打开可以对比一下