aipixel / GPS-Gaussian

[CVPR 2024 Highlight] The official repo for “GPS-Gaussian: Generalizable Pixel-wise 3D Gaussian Splatting for Real-time Human Novel View Synthesis”

Home Page:https://shunyuanzheng.github.io/GPS-Gaussian

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

关于GPS中raft-stereo深度估计算法的疑问

VillardX opened this issue · comments

作者您好,关于GPS中使用到的raft-stereo算法与其原始版本的区别,我有些疑问想请教。

关于fmap1和fmap2的cat问题:看源码和原始raft-stereo的主要区别在于fmap,在进入FlowUpdateModule前,进行了cat,按照左图1右图2的先后顺序分别得到fmap12和fmap21。

  1. 原始raft-stereo输入是两图,输出是左图的flow,所以不用concat,所以进入FlowUpdateModule的就是fmap1和fmap2?
  2. 而GPS中输入两图,希望同时获得这两张图的flow,所以做了cat处理,输入FlowUpdateModule的是fmap12和fmap21,后再进行split处理,以此同时得到左右图的flow?
  3. 进一步,之所以要区分fmap12和fmap21是因为CorrBlock1D下的 corr(fmap1, fmap2)计算是不可交换的,即torch.einsum('aijk,aijh->ajkh', fmap1, fmap2)torch.einsum('aijk,aijh->ajkh', fmap2, fmap1)返回结果不同,所以在原始输入在batch维度通过cat构造了 [(左,右),(右,左)] 两组样本,这样就能够在后续计算中同时输出了左图和右图的flow?

谢谢~

原始的raft-stereo目标是左视图深度,右视点的特征fmap2只用来构建cost volume但是没有在后续的GRU中用到,为了并行化节省计算开销,你可以看作我们把特征提取和后面的GRU模块独立开了,这样只要对图像分别提取一次特征。第3点里面你的理解是对的,是把提取出来的特征构建了[(左,右),(右,左)] 两组样本,目的就是为了同时输出左右两个flow,但是实际上,在工程化的时候,cost volume只计算一次就可以了,它是可以对称的,corr(fmap1, fmap2)的计算结果换一下索引就可以变成我们想要的另一个代价体corr(fmap1, fmap2)了,这一步在实际系统里面也是可以节省时间开销的。另外,第1点里面好像理解有问题,我记得原来的raft-stereo右视图的特征只用来构建cost volume,没有参与后续计算。

这里的v就是concat在一起的左右视图特征,x是左视图,只不过再分别过了卷积。v进一步在主函数拆分成fmap1和fmap2,这两个fmap在算完cost volume之后就没有再用到了,但是左视图相关的feature是参与GRU更新的。

  1. 您说的cost-volume实际上是指raft-stereo论文中3.2节式1的correlation-volume是吗?

  2. 关于第三点您说的可优化的地方,从raft-stereo原文公式上看,torch.einsum('aijk,aijh->ajkh', fmap1, fmap2)的结果通过互换k和h的索引即可得到torch.einsum('aijk,aijh->ajkh', fmap2, fmap1)的结果?

  3. v这一块看了下self.cnet输出的是*cnet_list和x,原始raft-stereo其实左右图都要做较浅的特征提取,输出v,再卷积得到fmap1和famp2用于计算correlation;做完浅层提取后(即您提到的v步骤之后的内容)再单独split出浅层左图特征进一步进行特征提取,输出*cnet_list?

  4. 而GPS的话不再区分左图和右图各自要做的特征提取(因为左图右图的flow都需要),所以*cnet_list同时包含了左图和右图深层特征用于后续的GRU迭代?

1和2都没错,cost vloume的计算是对称的,具体换哪两个维度试试就行了,应该是k和h没错。
第3点,做完特征提取之后实际上就一层卷积,他主要是想提现context feature和用于cost volume的feature分开,实际上区别不大,那个一层的卷积应该没有很大的影响。
第4点应该也是对的,但我没完全没看明白,raft-stereo也是要提取左右特征的,但是*cnet_list也就是这里的x扔掉了右视图的特征,我们把左右视图对保持叠在一起的状态了(叠在batch维度上),可以理解成GRU也share weights。

您好,感谢回复。我理解GPS和原版raft-stereo的区别了。

回到深度估计问题本身,我是这块内容的初学者。我理解没错的话,传统的双目深度估计底层原理是视差估计,即给予两幅完成极线校正的图像,在右图中寻找与左图匹配的各个像素点位置,并据此计算像素位置差(即视差)。再将视差转换为深度。

这类方法的局限在于,当两相机距离较大(即基线较大)或者两相机的朝向角度过小时,左图的一些像素点可能没有与之对应的右图像素,因此无法计算视差。

Raft-stereo底层逻辑还是双目深度估计,视差匹配(或者说是左右图的信息交互)这一过程应该就是在前面讨论的CorrBlock1D中完成的。实测下来,当基线变大时,深度估计的质量会有明显地下降;出现遮挡时时,这类问题会变得更严重。我的理解是大基线使得左图的一些特征点匹配不到右图,得到的correlation结果更像是神经网络“猜”出来的。

我在谷歌学术上也有follow到你们后续的工作,tele-aloha,我看文中的解决方案是使用级联架构(Fig8和Tab3),小基线相机的深度估计结果初始化大基线相机。按照文中的描述以及消融实验结果来看,该方案够达到没有初始化的iter=16的同等效果,但是总体误差相较于小基线还是有将近一倍(epe,2.192 vs 1.141),此外从Fig8看遮挡的问题还是存在。

我不清楚是否是因为双目深度估计“视差匹配”的底层原理决定了大基线深度估计效果的上限,如果想要解决大基线问题,是否需要考虑其他方案,比如MVS等?如果可以,还请您给一些建议,谢谢。

你好,我认为MVS应该也不能很好地解决大基线问题,而且双目stereo用卷积的方法,在遮挡处能够靠2d领域信息或者prior猜出一个合理的深度来,但是MVS里面用到的的cost volume和3D卷积,分辨率开不到足够大的话,在遮挡处或者匹配不上的区域效果应该更差,mvs的数据集视角之间都靠的比较近的。但是MVS的好处是可以融入多台相机,比如tele-aloha的设置用MVS可以直接用4台相机作为输入,但是可能计算效率会低很多。

解决大基线问题,可以看一下最近的Dust3r和pixelSplat,他们也是基于双目匹配的,但是backbone里面会有更多的attention,如果不是很追求实时性的话可以试一下这两篇文章的效果。如果在人体里面的话,更大基线的情况下可以尝试用多视角pifu这种隐式场的方法来得到一个初始值,前后左右四个视点一般就可以得到一个相对可用的人体几何了,同样,优化和加速也是需要的。

好的,感谢回复~