从头开始复盘一下MPI这条路线的始末,再次回顾这条线其实很多想法都会和之前不同,所以会以现在的观点重新审视。
开头
故事开始于PaintingNature这篇文章,该工作从2D的语义mask生成3D的场景,并且仅使用2D数据进行训练,他使用了一个语义场作为2D的语义mask和3D的rgb场之间的桥梁,将单张2D语义mask变换到多个其他视角并inpainting,然后用这些mask训练一个语义场,再从语义场获得更加连续的语义mask,并用SPADE转换成rgb图像,然后再用这些图像训练一个rgb的场。整个生成过程仍然过于繁琐,训练一个语义场和rgb场需要消耗太多时间和资源,无法实现端到端的生成,限制了该任务的实际应用。考虑到这一点,将文章中使用的光场替换成MPI看起来应该是更好的选择。MPI在本质上就是一个3D的图像,将原本的图像扩展成,这M张图像有各自的深度,代表场景下不同深度的内容,使得在不同视角看去时能达到3D的效果。
显而易见的是,MPI在生成上相比NeRF有着巨大的优势,NeRF使用mlp来表示场景,然而mlp的参数量巨大,无法使用网络进行生成。triplane使用了xy、yz、xz三个平面来获取feature,但仍需要一个统一的mlp将feature转换成颜色和密度,或许可以忽略mlp只生成三个plane,但是每个plane并没有3D上的物理意义,而且在渲染速度上也是远不及MPI的。MPI是由张图像组成的,在渲染时只需要将M张图像混合即可,既不需要采样也不需要多次经过mlp,所以在速度上是很快的,并且由于MPI的每一层都是一张真正的图像,那么语义MPI的每一层也都是一张真正的语义图,所以语义MPI和rgb的MPI之间,是可以直接进行转换的,即把语义MPI每一层的语义图直接通过SPADE转换成rgb图像,然后直接将所有图像组合成一个rgb的MPI。这种做法也是有先例的,如GVSNet,但是GVSNet需要三维的数据对网络进行训练,无法使用2D数据集,而因为从语义MPI到rgb MPI转换使用的SPADE需要能保持多视角连续,所以不能使用2D数据集预训练的SPADE,在PaintingNature中用AdaMPI的训练策略对GVSNet进行了训练,但是效果并不好。
于是我们的目的是,能够做到仅使用2D数据集进行训练,训好之后,输入语义mask,直接生成一个3D场景。其实现在来看,把GVS用AdaMPI的方式进行训练其实是没问题的,因为PaintingNature的训练方式和AdaMPI的思路是一致的,问题其实是为什么训不好,猜测可能是AdaMPI的inpainting网络的问题,但是总之我们很难想出区别于GVS的解决方案。
除此之外,还有一个需要重新考虑的问题,用3DGS代替MPI会如何。仔细想想其实是个不错的方向,首先,因为这个任务比较冷门,还没有人用3DGS去做这个任务,其次,3DGS完全可以做到用语义替换颜色,也可以做到语义场的效果,再者,3DGS的高斯球是可以用网络生成的,并且可以做到像MPI那样直接建立语义3DGS和rgb的3DGS之间的联系。于是主要难点就在于如何使用2D数据集建立这种联系,而且这种联系是语义高斯球与rgb高斯球之间的联系,并不是2D图像之间的联系,与之前不论是SPADE还是GVSNet做的事都不一样。
插曲
在对MPI研究过程中,Nex是唯一看到的一篇不做生成只做重建的MPI工作,和原版的3DGS、NeRF的任务相同。他主要解决的是View Depended问题,即在MPI中,从不同角度观察同一个点时,会得到相同的颜色,而现实中往往不是这样的,因此限制了MPI的重建能力,很多场景无法很好的表达,比如一些具有炫光的物品如光盘,或者具有反光光泽的材质如玻璃、金属等。为了解决这个问题,Nex为MPI的每层的每个像素扩展了会根据入射角方向不同而改变的颜色,并自己创建了一个具有上述材质的数据集,来验证方法的有效性。
MPI在重建时,场景的不同内容会重建在附近的平面上,那么平面的分布就十分影响整个场景重建的质量。AdaMPI、MINE、TiledMPI等,都不再会将MPI的每一层放在固定的深度上了,而是根据场景的不同将每个平面设置在不同的深度上,其中TiledMPI甚至会将平面等分成更小的平面,从而让平面的位置有更高的自由度。上述方法虽然给予了平面的深度更高的自由度,能更好地对不同场景的重建进行适应,但是由于整个平面的深度还是相同的,场景细节上的重建终究还是无法做的很好,因为细节越多,如果用同一平面进行表示,就必然会产生冲突,从而在质量上出现退化。于是我们的考虑是,让平面不再是平面,而是对平面的每个像素都赋予一个深度,让平面变得类似于曲面,这样曲面可以尽量去拟合场景中物体的表面,来提升重建的效果。
在技术上,将平面替换为曲面会出现一个求交点的问题,在MPI中,由于每一层平面的深度都是保持一致的,所以可以使用公式计算平面与光线交点的二维坐标,从而在平面上直接插值获得该点的颜色和透明度。但是替换成曲面后,光线与曲面的交点是无法用公式直接计算的,因为我们无法获得曲面的解析式,如果不能获得相对准确的交点的位置,训练就会出现问题。而我们的解决方案是求取一个近似解,如下图,
既然我们可以获得光线与平面的交点,我们就可以通过多次迭代,让光线与平面的交点逐渐逼近光线与曲面的交点。这种策略经过实验发现是奏效的,如果不使用重建会失败,在效果上经过观察其实对于复杂场景比较有效,但是有些场景的效果反而不大,其中缘由还是需要更多的实验和研究才行。而且Nex文中的分数我们其实没能复现出来,跑出来的结果分数还是偏低的,这其实导致了我们的结果分数也是偏低的,如果要继续下去,需要至少把分数刷到超过Nex、Light Field Neural Rendering、3DGS。但是按照我的经验感觉,PSNR可能可以超过,但是LPIPS和SSIM大概率很难刷过3DGS,这是MPI底层上的问题,具体原因会在后面讨论。
3DGS
上述其实提供了两个路子,一个是场景生成,一个是场景重建,MPI在重建上大概率很难再超过3DGS了,其实MPI也可以看作一个显式表达,而3DGS则可以看作MPI的上位替代,几乎涵盖了MPI的所有优势而且还具备MPI不具备的优点,所以在重建这条路上,我们找不到3DGS要和MPI结合的理由。而场景生成现在看来可能是更好走的一条路,这主要是基于以下几个原因。
首先我们要做的任务是从一张语义mask或者rgb图像生成对应的3D场景,而3DGS是非结构化的,高斯球的位置、数量都是不确定的,所以想要生成一个3DGS场需要先将3DGS结构化,主要是数量上首先要固定,比如一些工作会为每个像素生成一个高斯球,而如何结合MPI将3DGS结构化是需要研究的问题。
其次,3DGS和MPI的渲染在本质上是一致的,如上图,如果在不同深度上设置平面,然后将附近的高斯球渲染到附近的平面上,按照上图的公式将渲染出来的颜色与透明度转换为MPI中的颜色与透明度,再通过MPI的渲染公式渲染出来的图像,与将所有的高斯球直接渲染出来的图像,两者是一致的,两个渲染的过程也是等价的。然而这个等价仅仅限于MPI平面摆放与渲染视角一致的情况下才成立,如果平面的位置不变而渲染的视角发生改变,那结论成立与否或者两者有何关系还需要进一步的推导。
所以总结来说,将MPI与3DGS结合并非是不可能的,但是期望MPI能提升3DGS的重建能力大概是不太可能的,而如何使用MPI改进3DGS的生成则是之后需要考虑的问题。最后需要注意的是,我认为在技术上,将两者结合后,最终一定要使用3DGS或者2DGS的渲染器对场景进行渲染,原因一是拿MPI的方式渲染不一定能实现,既然有已有的渲染器不如直接拿来用,二是MPI的渲染效果一般,所以最好只吸收他的思路,用3DGS的渲染器能保持高质量的结果。