经典/深度SfM有关问题的整理

  这篇博客主要是记录一些实践或看论文过程中遇到的一些不好理解的问题及解释。
  
  Q1:SfM里的尺度不变性指的是什么?
  A1:一般定义下,尺度不变性是指体系经过尺度变换后,其某一特性不变。比如,特征点检测算法SIFT,其检测到的特征点的尺度不变性是通过图像金字塔来实现的。这样,不管原图的尺度是多少,在包含了所有尺度的尺度空间下都能找到那些稳定的极值点,这样就做到了尺度不变。关于SIFT尺度不变性的更详细讲解,可以参考这篇博客。
  
  Q2:单目相机SfM重建结果的尺度是怎么确定的?
  A2:传统方法中,单目重建是无法获取重建场景的尺度信息的。因此,要确定重建的尺度,需要使用额外的手段。比如:

  1. 已知某些物体的真实物理尺寸(或人为添加一个便于估算尺寸的物体一起进行重建),将其应用到重建出的三维空间中。
  2. 有其他传感器的辅助,比如深度传感器、LiDAR等可以提供参考。

  
  Q3:在初始化的时候,我们需要通过两张匹配的图像来使用对极几何约束求解相机外参。那么,已知图像对应匹配点,使用归一化八点法求出来的是E矩阵还是F矩阵?
  A3:在相机内参未知的情况下,如果使用的是像素坐标的对应点,那么求解出来的是F矩阵。在opencv上就有已经实现好的函数findFundamentalMat。然后,如果要进一步求解外参R和t,就需要获得E矩阵,然后通过E=t×R进行求解。E矩阵则需要通过其与F矩阵的关系来求解,即E=KTFK。但是,前面说到,相机内参是未知的。所以我们需要假设一个相机内参,可以设fx=fy=cx=w/2,cy=h/2。这里,w和h分别是图像的宽度和高度。虽然这样结果并不准确(这是必然的),但是这也算是未知内参情况下的一种切实可行的解决方案,且随着加入图像的增多以及BA的不断优化,重建的结果也会越来越好。
  
  Q4:图像的畸变是在BA时候才开始考虑的,那在初始化(第一次三角化和pnp)的时候怎么办?
  A4:如果没有对相机进行标定,或者重建的图像是一些网图的话,那么初始化的时候确实是没有考虑图像畸变的,这确实会造成不正确的结果。但是,对于增量式SfM而言,一开始其结果都是不准确的,需要靠后期不断加入新图像,不断进行BA来进行优化。
  
  Q5:深度学习方法中,图像的特征金字塔是怎么匹配的?
  A5:特征金字塔的构建方法一般是,将原图作为最底层的图像(分辨率最高),然后依次进行下采样,获得更高层的图像。在匹配时,将所有下采样得到的图像再上采样到与原始图像相同尺寸的大小,然后全部concatenate在一起,进行下一步处理。比如BANet就用到了图像金字塔。
  
  Q6:什么是逆深度空间,为什么要用逆深度空间?
  A6:逆深度(Inverse depth)是近年来SLAM研究中出现的一种广泛使用的参数化技巧。它使用深度的倒数(也就是逆深度)来进行参数化,因为逆深度的分布更贴近高斯分布。在实际应用中,逆深度也具有更好的数值稳定性,从而逐渐成为一种通用的技巧。其他常用的参数化方式,比如用(x, y, z)表示三维点坐标,xyz三个参数都是离散随机的;而使用图像坐标(u, v)再加上一个深度信息d,也可以表示三维点坐标。
  
  Q7:深度学习论文中的warp是指什么?
  A7:warp就是将一个图像上的点变换到另一张图像上。比如在构建cost volume的时候,会需要将源图像上的像素点,通过一系列虚拟平面,warp到目标图像上,然后计算其代价。
  
  Q8:每个虚拟平面上的每个像素点的值是什么?
  A8:每个像素点的值为该点的损失(cost)。
  
  Q9:平面扫描(plane sweep)时的一系列虚拟平面和左右视图是一样大小的吗?
  A9:通常假设的一系列虚拟平面是垂直于目标视图z轴的,这样的话,这些虚拟平面就和目标视图的长宽是一样的了。而在将源视图warp到目标视图上的时候,若其坐标范围超出了目标视图的长宽,则直接舍弃;而虚拟平面上没有cost(即没有对应点)的地方通常设为0。
  
  Q10:增量式SfM重建出的场景尺度是由初始匹配对的尺度决定的。通常SfM重建出的尺度与场景的实际尺度是不同的,那么,该如何将重建尺度与实际尺度进行统一?
  A10:SfM在进行三维重建时,并没有除图像以外的其他位置、或比例尺信息,本质上是在一个任意坐标系下进行三维重建的。因此,重建的结果与实际的场景之间相差一个相似变换(尺度、旋转、平移)。可以通过控制点或者GNSS信息进行绝对定向,也可以通过已知物体的真实尺度与重建尺度,进行缩放求解。
  
  Q11:如果已经拥有一个场景重建的真值,现在又重建了一个三维场景,如何将新的场景与真值进行尺度、位置等的配准?
  A11:首先分别求解两个点云场景的坐标重心,然后分别获得两个重心到对应场景最远的一个点,将其连成一条线。基于这两条向量就能实现缩放旋转的配准了。当然这样误差可能会比较大,可以通过取更多的点来进一步减小误差。
  
  Q12:track就是特征点吗?
  A12:一个track是同一三维点在不同图像上被观测到的对应像素点,将这些像素点合起来称为track。track被观测到的次数越多表示这个三维点越稳健。在OpenMVG里,track只有2的三维点是会被直接舍弃掉的。
经典/深度SfM有关问题的整理_第1张图片
  
  Q13:本质矩阵E与基础矩阵F有什么关系,它们与像素点和归一化坐标点之间怎么对应?
  A13:有如下三个等式:

E=t[×]R
F=K-TEK-1
x2TEx1=p2TFp1=0

  其中,R和t分别是第二个相机的旋转矩阵和平移向量,t[×]则是向量t的反对称矩阵,K是相机内参,x表示归一化平面上的点,p表示像素坐标系下的像素点,p与x之间存在关系p=Kx。
  
  Q14:如何将重建出来的场景与真值进行对齐?
  A14:SfM重建出来的场景是尺度未定的,与真值(如果有的话)之间会相差一个相似变换,这个相似变换的求解及代码可以参考相机对齐方法介绍及实现代码(相似变换,包含旋转R、平移t、尺度s)。
  
  Q15:colmap里坐标系是怎么定义的?左手系还是右手系?
  A15:colmap是右手系,它的坐标系定义和OpenCV一样,x: right, y: down, z: backward。
  
  Q16:深度图中的深度是怎么定义的
  A16:要记录每个像素对应的深度,有两种方式。一种是记录每个像素对应真实点沿光线到相机中心的距离,另一种则是记录每个像素对应真实点在相机坐标系下的Z值。一般我们所说的深度图,其深度定义都是后者。因为如果是前者,那么比如我使用相机正对着一面墙去拍摄,其深度图上离图像中心越远,则深度越大。但是我们会希望,与成像平面平行的平面,则其上的每一个像素的深度都是一致的,而第二种定义方式才符合这种期望。关于mesh转深度图的代码,可以参考高效率mesh转深度图python代码。
  
*持续更新中 ~

你可能感兴趣的:(SfM,sfm)