Closed 520jz closed 3 months ago
您好,我们的方法是通过为输入的source views构造cost volume来得到target view下的每个像素的深度,然后建立pixel-aligned的Gaussian表征,即根据预测的深度将像素反投影到3D空间得到对应3D点,得到的3D点就作为高斯球的中心,即position。由于是pixel-aligned,且每个像素对应一个Gaussian,所以这种情况下通过cost volume得到的深度和利用3D高斯累积的方式得到的深度其实是一样的。
即我们的方法显式地通过cost volume先得到了深度,然后再建立Gaussian表征的。
您好,我们的方法是通过为输入的source views构造cost volume来得到target view下的每个像素的深度,然后建立pixel-aligned的Gaussian表征,即根据预测的深度将像素反投影到3D空间得到对应3D点,得到的3D点就作为高斯球的中心,即position。由于是pixel-aligned,且每个像素对应一个Gaussian,所以这种情况下通过cost volume得到的深度和利用3D高斯累积的方式得到的深度其实是一样的。
即我们的方法显式地通过cost volume先得到了深度,然后再建立Gaussian表征的。
哦哦哦,那通过构建cost volume得到深度这种方式是否是可学习的呢?我看通过3D高斯累积的方式得到的深度好像是不可学习的?因为没用到网络。因此具体来说应该还是通过构建cost volume这种方式得到的深度效果更好?
构建cost volume得到深度需要用到网络,是可学习的,这种显式地预测深度可能精度会更高,但相比之下的缺点是额外的网络引入会影响推理速度、计算开销。
构建cost volume得到深度需要用到网络,是可学习的,这种显式地预测深度可能精度会更高,但相比之下的缺点是额外的网络引入会影响推理速度、计算开销。
明白了,谢谢大佬
构建cost volume得到深度需要用到网络,是可学习的,这种显式地预测深度可能精度会更高,但相比之下的缺点是额外的网络引入会影响推理速度、计算开销。
大佬,我发现训练过程以及渲染的时候好像不会把深度图保存和输出?
您好,可以运行下面的命令得到深度图以及点云:
python run.py --type evaluate --cfg_file configs/mvsgs/llff_eval.yaml save_ply True
上述结果默认保存在mvsgs_pointcloud文件夹下,也可以通过添加dir_ply <save path>
来指定保存的路径,即:
python run.py --type evaluate --cfg_file configs/mvsgs/llff_eval.yaml save_ply True dir_ply <save path>
通过更换上述的config文件cfg_file
,可以得到不同数据集的结果。
如果想在训练过程中也保存深度图,可以修改这里,目前的代码只会保存渲染的RGB图像和对应GT,如有需要,您可以修改代码增加保存深度图,深度图的保存代码可参考这里。
您好,可以运行下面的命令得到深度图以及点云:
python run.py --type evaluate --cfg_file configs/mvsgs/llff_eval.yaml save_ply True
上述结果默认保存在mvsgs_pointcloud文件夹下,也可以通过添加
dir_ply <save path>
来指定保存的路径,即:python run.py --type evaluate --cfg_file configs/mvsgs/llff_eval.yaml save_ply True dir_ply <save path>
通过更换上述的config文件
cfg_file
,可以得到不同数据集的结果。如果想在训练过程中也保存深度图,可以修改这里,目前的代码只会保存渲染的RGB图像和对应GT,如有需要,您可以修改代码增加保存深度图,深度图的保存代码可参考这里。
明白了,谢谢大佬!respect!
您好,可以运行下面的命令得到深度图以及点云:
python run.py --type evaluate --cfg_file configs/mvsgs/llff_eval.yaml save_ply True
上述结果默认保存在mvsgs_pointcloud文件夹下,也可以通过添加
dir_ply <save path>
来指定保存的路径,即:python run.py --type evaluate --cfg_file configs/mvsgs/llff_eval.yaml save_ply True dir_ply <save path>
通过更换上述的config文件
cfg_file
,可以得到不同数据集的结果。如果想在训练过程中也保存深度图,可以修改这里,目前的代码只会保存渲染的RGB图像和对应GT,如有需要,您可以修改代码增加保存深度图,深度图的保存代码可参考这里。
大佬您好,我还想再问一个问题,您知道三通道的深度图怎么转成单通道深度图吗?或者转成.exr格式,比如下面这个代码他就是从.exr文件中读取HxW的深度信息就只有一个通道
您好,三通道深度图指的是伪彩色的深度图吗
您好,三通道深度图指的是伪彩色的深度图吗
什么是伪彩色深度图呢?我用的您的模型渲染出来的深度图,您的这个是伪彩色的吗?
您好,三通道深度图指的是伪彩色的深度图吗
我现在想获得这个深度值HxW,但是现在我只有渲染出来的这种RGB颜色的深度图,怎么衔接到这个代码上呢?去得到HxW的深度图。
您好,因为深度图是单通道的,为了更好的可视化,我们一般会将其转换为伪彩色图像,即三通道的。 在这里,即下面一行:
rendered_depth_vis, _ = visualize_depth(depth_vis, depth_minmax)
depth_vis
的shape是HxW, rendered_depth_vis
的shape是3xHxW。
我们在visualizedepth函数里通过`x = Image.fromarray(cv2.applyColorMap(x, cmap))将单通道转换为三通道,以便可视化。如果仅需要单通道的深度图,您可以跳过这个转换的操作,直接保存
depth_vis`即可。
您好,因为深度图是单通道的,为了更好的可视化,我们一般会将其转换为伪彩色图像,即三通道的。 在这里,即下面一行:
rendered_depth_vis, _ = visualize_depth(depth_vis, depth_minmax)
depth_vis
的shape是HxW,rendered_depth_vis
的shape是3xHxW。 我们在visualizedepth函数里通过`x = Image.fromarray(cv2.applyColorMap(x, cmap))将单通道转换为三通道,以便可视化。如果仅需要单通道的深度图,您可以跳过这个转换的操作,直接保存
depth_vis`即可。
明白了,太感谢您了,大佬,谢谢您!
您好,因为深度图是单通道的,为了更好的可视化,我们一般会将其转换为伪彩色图像,即三通道的。 在这里,即下面一行:
rendered_depth_vis, _ = visualize_depth(depth_vis, depth_minmax)
depth_vis
的shape是HxW,rendered_depth_vis
的shape是3xHxW。 我们在visualizedepth函数里通过`x = Image.fromarray(cv2.applyColorMap(x, cmap))将单通道转换为三通道,以便可视化。如果仅需要单通道的深度图,您可以跳过这个转换的操作,直接保存
depth_vis`即可。
大佬,不好意思,可以再问一个问题吗?就是python run.py --type evaluate --cfg_file configs/mvsgs/llff_eval.yaml save_ply True这个命令是可以得到深度图以及渲染的图片的,但是为什么分辨率是640x960呢?这个渲染的分辨率可以修改吗?而且我发现渲染的这个分辨率并不是原llff图片分辨率的整数倍,原llff图片的分辨率是3024x4032。
分辨率可以在这里修改,W和H需要是32的整数倍。
哦哦哦,谢谢大佬,我最近突然发现一个奇怪的问题,为什么估计的深度(包括很多深度估计模型)其深度值的大小和实际的深度是相反的,比如深度越深其深度值应该越大才对,深度越浅其深度值应该越小才对,但是观察最终的深度数组发现并不是这样的。下面是我测试的deepth anything以及GaussianPro(其是用高斯累积计算的深度)模型的结果。MVSGaussian我还没来得及测试,因为对于这个街景的数据集好像要单独的训练一下,直接用dtu训练好的预训练模型还不能重建出这种街景的数据集。大佬您如果知道为什么深度值的大小会是相反的可以告诉我一下吗? 您看,深度数组最下面的几行数据应该是要小于上面的才对,因为明显街道越靠里面,深度越深数值越大才对
后面我换了一个深度估计模型Marigold,其估计的数值是正常的符合人为直觉的
Depth-Anything、MiDaS他们输出的相对深度类似于视差,真实深度是要再取个倒数的,您可以看一下这里。
大佬,你简直是我的神!太感谢了,但是好像简单的求倒数是不行的,有两个参数A和B只能通过真实深度求出来,为什么不直接输出就是真实深度呢,这样方便多了Marigold输出的就好像就是真实深度,那MVSGaussian的输出深度是真实深度还是相对深度呢?我想在MVSgs的基础上做改进
Depth-Anything、MiDaS他们输出的相对深度类似于视差,真实深度是要再取个倒数的,您可以看一下这里。
大佬,你简直是我的神!太感谢了,但是好像简单的求倒数是不行的,有两个参数A和B只能通过真实深度求出来,为什么不直接输出就是真实深度呢,这样方便多了Marigold输出的就好像就是真实深度,那MVSGaussian的输出深度是真实深度还是相对深度呢?我想在MVSgs的基础上做改进
实际上我发现,如果直接求倒数的话得到的可视化效果是这样的,或许直接求倒有些小问题,我需要再去研究研究,谢谢大佬点拨 可视化的函数用的是MVSGS中的visualize_depth
如果不求倒的话可视化的效果是这样的:
对是的,不能直接简单地求倒数,要得到绝对深度还需要估计两个参数scale(A)和offset(B)。 据我了解,单目深度估计方法中有估计相对深度的(relative (ordinal) depth),也有估计绝对深度的(metric depth),depth-anything同时提供了Relative depth estimation和Metric depth estimation。 相对深度由于只需要区分像素之间的空间顺序关系,并且有些相对深度的数据集的GT是通过双目匹配或者光流匹配得到的,所以直接输出相对视差(逆相对深度),这样可能更方便监督。而对于metric depth estimation,一般会在有绝对深度GT的NYUv2或者KITTI数据集上微调得到,可参考ZoeDepth。
另外,MVSGaussian的输出深度是绝对深度,不是相对深度。
对是的,不能直接简单地求倒数,要得到绝对深度还需要估计两个参数scale(A)和offset(B)。 据我了解,单目深度估计方法中有估计相对深度的(relative (ordinal) depth),也有估计绝对深度的(metric depth),depth-anything同时提供了Relative depth estimation和Metric depth estimation。 相对深度由于只需要区分像素之间的空间顺序关系,并且大部分相对深度的数据集的GT是通过双目匹配或者光流匹配得到的,所以直接输出相对视差(逆相对深度),这样可能更方便监督。而对于metric depth estimation,一般会在有绝对深度GT的NYUv2或者KITTI数据集上微调得到,可参考ZoeDepth。
另外,MVSGaussian的输出深度是绝对深度,不是相对深度。
哦哦哦,明白了,谢谢大佬!
对是的,不能直接简单地求倒数,要得到绝对深度还需要估计两个参数scale(A)和offset(B)。 据我了解,单目深度估计方法中有估计相对深度的(relative (ordinal) depth),也有估计绝对深度的(metric depth),depth-anything同时提供了Relative depth estimation和Metric depth estimation。 相对深度由于只需要区分像素之间的空间顺序关系,并且大部分相对深度的数据集的GT是通过双目匹配或者光流匹配得到的,所以直接输出相对视差(逆相对深度),这样可能更方便监督。而对于metric depth estimation,一般会在有绝对深度GT的NYUv2或者KITTI数据集上微调得到,可参考ZoeDepth。
另外,MVSGaussian的输出深度是绝对深度,不是相对深度。
大佬为什么我四张卡一起跑,batch_size设置的为1但还是爆显存呢?我是4090,我记得您好像也是用的4090是吧?难道是我这个数据集图片太大了吗?我记得.yaml文件里面设置的H和W好像会将图片自动裁剪到对应的大小,应该数据集无论多大,只要.yaml文件中的H和W设置保持不变就不影响显存占用吧。
我的命令如下: python -m torch.distributed.launch --nproc_per_node=4 train_net.py --cfg_file configs/mvsgs/colmap_eval.yaml train_dataset.data_root nerf_llff_data/street test_dataset.data_root nerf_llff_data/street distributed True gpus 0,1,2,3 train.batch_size 1
您可能需要调整一下scale_factor
的值,应该是需要调大一些。对于scale_factor
的含义,请参考这里,即:
Modify the value of scale_factor. Since our model is trained on DTU data set (depth range is 425~905), when testing on other new datasets, we use scale_factor to adjust the depth of the new scenario to be close to the depth of the DTU dataset. For example, for the nerf synthetic dataset with a depth range of 2.5 to 5.5, we set scale_factor to 200, and for the LLFF dataset with a depth range of about 20 to 100, we set it to 12. You would try modifying scale_factor here.
您可能需要调整一下
scale_factor
的值,应该是需要调大一些。对于scale_factor
的含义,请参考这里,即:Modify the value of scale_factor. Since our model is trained on DTU data set (depth range is 425~905), when testing on other new datasets, we use scale_factor to adjust the depth of the new scenario to be close to the depth of the DTU dataset. For example, for the nerf synthetic dataset with a depth range of 2.5 to 5.5, we set scale_factor to 200, and for the LLFF dataset with a depth range of about 20 to 100, we set it to 12. You would try modifying scale_factor here.
哦哦哦,明白了大佬,我还想再问一个跟网络有关的问题,就是您设计的这种编码——解码网络结构,最终通过MLP去解码出高斯椭球的相关参数,我很好奇您是怎么知道这样就能预测到高斯椭球的相关参数的呢,其实我最想知道的是这种结构除开预测高斯椭球的相关参数之外还可以预测其他参数吗?比如跟图像本身相关的一些参数,比如光度信息啥的,当然我这里只是举例,我是想说可否预测图像本身的相关信息,因为这个网络也对图像提取了特征的嘛。
您好,我们的这种设计是受到之前泛化性NeRF方法的启发,泛化性NeRF的大体范式是为采样的3D点编码特征,然后通过MLP解码得到体密度volume density和颜色值radiance,最后使用体渲染得到新视图。volume density表征场景的几何信息,radiance表征场景的外观信息,所以编码的特征一般需要是几何感知的(cost volume-based)和外观感知的(汇聚多视图的外观特征)。我们的MVSGaussian是将这套编解码的思想迁移到了3DGS上,我们认为同样可以解码得到高斯球的属性。其他的一些基于3DGS的泛化新视图合成方法,比如pixelsplat,GPSGaussian等等,大体也是遵循这么一个思想。
关于能否预测图像本身的相关信息,效果得到具体的任务上去试试,我认为理论上是有这个能力的。
您好,我们的这种设计是受到之前泛化性NeRF方法的启发,泛化性NeRF的大体范式是为采样的3D点编码特征,然后通过MLP解码得到体密度volume density和颜色值radiance,最后使用体渲染得到新视图。volume density表征场景的几何信息,radiance表征场景的外观信息,所以编码的特征一般需要是几何感知的(cost volume-based)和外观感知的(汇聚多视图的外观特征)。我们的MVSGaussian是将这套编解码的思想迁移到了3DGS上,我们认为同样可以解码得到高斯球的属性。其他的一些基于3DGS的泛化新视图合成方法,比如pixelsplat,GPSGaussian等等,大体也是遵循这么一个思想。
关于能否预测图像本身的相关信息,效果得到具体的任务上去试试,我认为理论上是有这个能力的。
哦哦哦,明白了,谢谢大佬!太感谢您了
您好,我们的这种设计是受到之前泛化性NeRF方法的启发,泛化性NeRF的大体范式是为采样的3D点编码特征,然后通过MLP解码得到体密度volume density和颜色值radiance,最后使用体渲染得到新视图。volume density表征场景的几何信息,radiance表征场景的外观信息,所以编码的特征一般需要是几何感知的(cost volume-based)和外观感知的(汇聚多视图的外观特征)。我们的MVSGaussian是将这套编解码的思想迁移到了3DGS上,我们认为同样可以解码得到高斯球的属性。其他的一些基于3DGS的泛化新视图合成方法,比如pixelsplat,GPSGaussian等等,大体也是遵循这么一个思想。
关于能否预测图像本身的相关信息,效果得到具体的任务上去试试,我认为理论上是有这个能力的。
大佬,我发现调用colmap_eval.yaml文件的时候也会调用dtu_pretrain.yaml文件,这两个文件里面都有scale_factor参数,最终scale_factor参数是由colmap_eval.yaml文件决定还是dtu_pretrain.yaml文件决定呢?还有就是您觉得像这种街景的数据集scale_factor这个参数是越大越好还是设置的越小越好呢?
您好,调用colmap_eval.yaml文件时,如果dtu_pretrain.yaml文件有相同的参数,则会被colmap_eval.yaml里的参数覆盖,即scale_factor参数是由colmap_eval.yaml文件决定的。
对于scale_factor的设置,需要根据场景的depth range深度范围来确定,因为我们提供的预训练模型是在DTU数据集上训练的,DTU数据集的深度范围是425~905
,所以街道场景的depth range*scale_factor
大致落在425~905这个量级就可以,您可以尝试几组数值来进行比较。
您好,调用colmap_eval.yaml文件时,如果dtu_pretrain.yaml文件有相同的参数,则会被colmap_eval.yaml里的参数覆盖,即scale_factor参数是由colmap_eval.yaml文件决定的。 对于scale_factor的设置,需要根据场景的depth range深度范围来确定,因为我们提供的预训练模型是在DTU数据集上训练的,DTU数据集的深度范围是
425~905
,所以街道场景的depth range*scale_factor
大致落在425~905这个量级就可以,您可以尝试几组数值来进行比较。
哦哦哦,明白了,谢谢大佬,还有我想问的是,您在用dtu数据集进行训练的时候有用到他的GT的depth吗?还是说只需要用到对应的RGB和pose就可以了?
训练的时候没有用depth GT,只需要RGB和pose即可。不过,在评估的时候会用到DTU数据集里的depth GT,用来测深度预测的精度。
训练的时候没有用depth GT,只需要RGB和pose即可。不过,在评估的时候会用到DTU数据集里的depth GT,用来测深度预测的精度。
明白了,谢谢大佬!
训练的时候没有用depth GT,只需要RGB和pose即可。不过,在评估的时候会用到DTU数据集里的depth GT,用来测深度预测的精度。
大佬您好,我看dtu数据集有好几个depth,具体哪个depth才是GT呢?而且我发现这些depth大小和RGB图片大小不一样欸,rgb图片大小是512x640,但是depth的大小有两种分别是128x160以及1200x1600
我们用的深度GT是 Depths_raw/{}/depth_map_{:04d}.pfm'.format(scene, i)
, 请参考 这里.
我们用的深度GT是
Depths_raw/{}/depth_map_{:04d}.pfm'.format(scene, i)
, 请参考 这里.
哦哦哦,明白了,谢谢大佬,大佬我还想问一下为什么mvsgs的特征提取网络跟mvsnet的不太一样呢?我看mvsgs好像多加了几层卷积层,并且返回了三个特征图,可以解释一下这样做的原理吗?
对,和原始的MVSNet不是完全一样的,我们采用了一种coarse-to-fine(cascaded)的框架,先对降采样的图像处理来得到场景的大致的(coarse)深度估计,在此基础上再对高分辨率的图像进行处理,得到精细的(fine)深度估计和视图合成。这种策略的优势在于可以降低显存消耗。可以参考CasMVSNet论文,它是针对MVSNet显存消耗大而提出了coarse-to-fine的结构进行处理。
mvsgs的特征提取网络返回的三个特征图也就是不同size的特征图,以供给不同阶段(coarse or fine)使用。
对,和原始的MVSNet不是完全一样的,我们采用了一种coarse-to-fine(cascaded)的框架,先对降采样的图像处理来得到场景的大致的(coarse)深度估计,在此基础上再对高分辨率的图像进行处理,得到精细的(fine)深度估计和视图合成。这种策略的优势在于可以降低显存消耗。可以参考CasMVSNet论文,它是针对MVSNet显存消耗大而提出了coarse-to-fine的结构进行处理。
mvsgs的特征提取网络返回的三个特征图也就是不同size的特征图,以供给不同阶段(coarse or fine)使用。
大佬,为什么mvsgs中提取特征只提取了源视图的特征没有提取目标视图的特征呢?我记得mvsnet好像是提取了所有图像的特征,如果只提取源视图的特征那在进行单应性变换构建代价体的时候,源视图和目标视图不就难以匹配了,因为源视图是高维度的特征数据,而目标视图仍然是rgb数据。 还有就是pairs.th中的数据是什么数据呢?为什么里面有其他各个场景的名字?
我们的任务的输入是一组源视图,输出是目标视图,所以mvsgs只能提取输入的源视图特征,而目标视图在推理过程中是不可知的。MVSNet是根据多视图来预测深度,不是新视图合成任务,所以可以提取所有图像的特征。
pairs.th里有training set和test set的图像序号(id),在推理评估的时候,指定一个test视角,选择与其最接近的N幅training set中的视图作为输入,网络合成的test视图会与test set里相应的GT视图计算指标。
我们的任务的输入是一组源视图,输出是目标视图,所以mvsgs只能提取输入的源视图特征,而目标视图在推理过程中是不可知的。MVSNet是根据多视图来预测深度,不是新视图合成任务,所以可以提取所有图像的特征。
pairs.th里有training set和test set的图像序号(id),在推理评估的时候,指定一个test视角,选择与其最接近的N幅training set中的视图作为输入,网络合成的test视图会与test set里相应的GT视图计算指标。
哦哦哦,但是我理解的是,mvsnet里面是根据目标视图(Target images)的frustum分割成多个不同深度的平面,然后将其像素值warp到不同的平面上,然后将源视图(Source image)的像素经过单应性变换也投影到不同的平面上并与目标视图上的值进行比较。如果mvsgs输入的只是源视图,那frustum是根据谁的构建,对应的不同层次的深度是通过目标视图的frustum构建还是源视图的frustum构建呢?因为要先构建frustum然后再继续构建对应的cost volume吧
对的,您的理解是正确的。对于MVSNet来说,是在目标视图的frustum里建立cost volume。类似于mvsnet,mvsgs也是在目标视图的frustum里建立cost volume的,不同的是mvsgs的目标视图的RGB是不可知的。将源视图的像素warp到目标视角的深度平面,然后用方差来融合这些warped source feature来得到cost。
对的,您的理解是正确的。对于MVSNet来说,是在目标视图的frustum里建立cost volume。类似于mvsnet,mvsgs也是在目标视图的frustum里建立cost volume的,不同的是mvsgs的目标视图的RGB是不可知的。将源视图的像素warp到目标视角的深度平面,然后用方差来融合这些warped source feature来得到cost。
哦哦哦,但是这样的话用什么做监督和约束呢?将源视图的像素warp到目标的深度平面,但是目标深度平面上并没有目标视图对应的像素。
中间没有监督,只在最后用RGB GT监督合成的RGB。 “将源视图的像素warp到目标的深度平面,但是目标深度平面上并没有目标视图对应的像素”是对的,这时候直接算warp得到的N幅源视图的特征之间的方差就行。因为如果某深度平面是准的,那么warp得到的源视图的特征之间的相似性应该较高,即方差较小;反之方差较大。当然这是在不考虑遮挡等问题的前提下。
中间没有监督,只在最后用RGB GT监督合成的RGB。 “将源视图的像素warp到目标的深度平面,但是目标深度平面上并没有目标视图对应的像素”是对的,这时候直接算warp得到的N幅源视图的特征之间的方差就行。因为如果某深度平面是准的,那么warp得到的源视图的特征之间的相似性应该较高,即方差较小;反之方差较大。当然这是在不考虑遮挡等问题的前提下。
哦哦哦,我好像明白一些了,我再去看看源码,谢谢大佬
中间没有监督,只在最后用RGB GT监督合成的RGB。 “将源视图的像素warp到目标的深度平面,但是目标深度平面上并没有目标视图对应的像素”是对的,这时候直接算warp得到的N幅源视图的特征之间的方差就行。因为如果某深度平面是准的,那么warp得到的源视图的特征之间的相似性应该较高,即方差较小;反之方差较大。当然这是在不考虑遮挡等问题的前提下。
大佬这里累积透射率T的计算感觉不太理解,[..., -1]这个操作的话,透射率T就是空的了,后面一行又拼接了全1的张量,那透射率不就是全1的了吗?累积透射率不应该是全1的吧?
天呐,这是什么神仙作者,这么细致的回复这么多纯小白问题,太赞了!
作者您好,非常感谢您出色的工作,我想问一下您的论文中为什么不采用通过3D高斯累积的方式来构建深度图呢?比如下面的图片所示:
这种深度计算方式相比于通过cost volume的计算深度图的方式哪种更好呢?