Q1 -- 什么是sba?
sba是一个C/C++软件包对广义稀疏光束平差,在GNU公共许可证下分发。sba是通用的,提供关于定义涉及光束法平差的图像投影的参数选择和函数关系增强的灵活性。
Q2 -- 什么是光束法平差?
假设给定一系列图像中观测到的一组对应点集相应的三维坐标的初始估计,以及关于每张图像的viewing参数的初始估计。光束法平差(BA)是一个大的最优化的问题,包括同时精化三维结构和viewing参数(即相机姿态和可能的本征校准和径向畸变),为了获得一个在特定的假设下最优化的重建,考虑与观测的图像特征有关的噪声:如果图像误差满足均值为零的正态分布,那么BA是最大似然法估计。它的名字“bundles”(光束)源于每个三维特征聚焦于每个相机的光学中心,这些光学中心相对于结构和viewing参数进行最优化的调整。sba使用Levenberg-Marquardt非线性最小二乘算法的常规实现来解决与BA相联系的稀疏的大规模的优化问题。
Q3 -- “稀疏”是什么意思?
由于不同的三维点和相机之间没有相互影响,BA过程中必须解决的线性系统(即法方程)包含许多零并且形成了一个稀疏的块结构特征。这种结构可以通过避免存储和处理零元素来利用,从而获得可观的计算效益。
Q4 -- 为什么通用的优化代码不能用于实现BA?
BA涉及大规模最小化问题的解决,一般涉及上千个变量。优化算法通过迭代的进行函数的线性化,在当前估计的周围进行最小化并且获得线性系统(它的解确定了当前估计的一个增量)。大多数优化代码(如,minpack,nl2sol/n2g 等)假设这些线性系统是稠密的,即包含很多非零元素。已知的几个这种系统的计算复杂度是O(n**3)。调用BA涉及到大规模最小化问题的解(一般涉及上千个变量),所以很明显大多数通用的优化代码在应用BA时会引起运行效率降低和存储容量增大。
Q5 -- 在哪里可以找到更多的关于光束法平差的信息?
关于BA的在基于视觉的重建中的应用的一个优秀的综述:Triggs 等人的Bundle Adjustment: A Modern Synthesis。更简短的说明,可参考 bundle adjustment article in Wikipedia。
Q6 -- 在哪里可以找到更多关于Levenberg-Marquardt算法的信息?
参考讲稿Methods for Non-Linear Least Squares Problems, by K. Madsen, H.B. Nielsen and O. Tingleff, Technical University of Denmark, 2004.
Q7 -- sba支持哪些类型的光束法平差?
Sba 给它的用户对于描述相机和三维结构的参数定义的完全的控制。因此,它可以支持不同的多视重建问题的实例,如投影重建,几何重建,本征相机参数精化,等等。Sba也提供了程序处理前方交会和后方交会问题,其中相机姿态和场景结构分别保持不变。
Q8 -- 谁在使用sba?
Sba对于计算机视觉、机器人、基于图像的图形学、摄影测量、测量、制图等领域的研究者和从业者是无价的。它已经在全球许多实验室中使用,并且也是世界范围内以源代码方式提供的GNU GPL许可证而且授权商用的软件。如果你想要知道更多关于sba的用途方面的信息,以下是我们列出的使用了sba的论文列表here。
Q9 -- 使用sba时我需要什么?
为了能够使用所有的sba函数,必须安装LAPACK或者等价的库,检查http://www.netlib.org/clapack的f2c'ed的免费版本。据报告上述站点上的预编译的MSWin库损坏了,需要使用工程文件重新构建。你也可以尝试这些预编译的MSWin LAPACK/BLAS 库。
Q10 -- 我怎么样编译sba?
首先,你必须保证在本地安装了LAPACK。如果你必须安装它,请遵循以下安装说明包括LAPACK的分发。第二步是编译sba本身。tar压缩包包含Unix/Linux下使用gcc的makefile文件以及MSWin下使用Visual Studio的Makefile.vc。请阅读这些文件中的注释以获得更多信息。基于提供的makefile文件,它可以使用任何符合ANSI的编译器来直接编译。
Q11 -- 为什么我得到一个未确定的外部符号dgesdd的链接错误?
可能是因为你的LAPACK是旧的版本。Dgesdd在LAPACK3.0中引入。如果你不想升级,你可以选择使用稍微慢一点的dgesvd。Sba_lapack.c对于注释中的dgesvd有类似的调用。
Q12 -- 不同的事物参数在哪里有详细的解释?
参考 ICS/FORTH TR-340: The Design and Implementation of a Generic Sparse Bundle Adjustment Software Package Based on the Levenberg-Marquardt Algorithm, by M.I.A. Lourakis and A.A. Argyros, 2004. 源代码中也包含了每个函数的每个参数的注释。
Q13 -- 怎样把sba改编为我自己的BA变体?
如上所述,sba在选择描述相机、三维结构和图像投影的函数关系和参数时非常灵活。因此,它可以支持许多种类的BA,包括任意投影或者仿射相机,部分地活着完全的本征标定相机,外方位元素(即姿态)估计,从特定的三维点、本征标定图像的三维重建,本征标定参数的精化,等等。为了把sba改编为一个特定的问题,用户必须对相机和三维结构选择一个合适的参数化方法,然后提供相应的投影函数以及它的函数行列式的实现代码。包括sba的演示程序更详细的阐述了处理几何BA问题的细节。
Q14 -- 如何计算sba重建的初始点?
由于BA涉及一个迭代最小化问题的解,不同参数的初始估计应该提供给sba。这种估计定义了一个初始的三维重建并且可以使用任何结构或者运动估计视觉算法来计算,如 Hartley and Zisserman's 的书里面描述的方法。
Q15 -- sba对outlying数据稳健吗?
短的回答:No。
长的回答:假设图像点特征的局部误差时零平均的正态分布,BA是最大似然法估计。正是由于这个性质,使得BA如此强大,同时精化三维结构和viewing 参数。然而,注意,前述的假设不包括有gross outliers(即不匹配的特征)的情况。这些outlying特征应该在BA之前使用几何方法检测和消除。这种方法的更多的细节,在这里。
Q16 -- 怎样避免指定事务来计算投影函数行列式?
通过传入NULL作为函数行列式的对应参数,函数行列式在前向有限差分方法的辅助下进行计算。然而,注意,我们不推荐这种选择:为了获得最大的效率,我们建议提供一个函数解析的评估函数行列式。
Q17 -- 我们如何通过投影函数和函数行列式来传入和使用我们自己的数据?
设想你想传入两个数组,一个是double型的,一个是integer型的。一个快速并且有效的方法是使用全局变量。避免使用全局变量的最简单的方法是声明一个结构体如下
struct mydata{
double dar[XXX];
int iar[YYY];
};
其中XXX和YYY表示合适的数组大小。然后,定义一个结构体变量:
struct mydata data;
然后赋值:
data.dar[0]=7.0;
data.iar[0]=-17;
// etc
然后,调用合适sba程序,传入数据的地址作为参数,如:
ret=sba_motstr_levmar(..., proj, projac, (void *)&data, itmax, verbose, opts, info);
你的proj 和 projac 程序需要使用类型转换来解析提供的数据:
struct mydata *dptr;
dptr=(struct mydata *)adata; // adata is passed as void *
// supplied data can now be accessed as dptr->dar[0], etc
Q18 -- 我如何检验用户提供的jacobi行列式?
文件sba_chkjac.c包括检查传入BA函数的函数行列式的正确性(即用户提供的投影函数的一致性)函数。这些函数可以直接调用,通过将所有的sba_XXX_levmar() 和 sba_XXX_levmar_x() 中的itmax的值指定为0。这种情况下,这些函数立即返回0。检查函数输出可能的梯度(即函数行列式的行)到stderr。然而,我们应该注意,这些函数并不是100%安全可靠的,因为他们依赖点的评估,他们可能报告函数行列式是正确的。解决这种问题的方法是试着检查其它点Point(s)处的函数行列式的正确性。参考sba_chkjac.c查看更多细节。同时,记住这些函数是为了检查解析函数行列式,而不是有限差分的数值近似。
Q19 -- 为什么我获得一个LAPACK错误:函数sba_Axb_Chol()中错误的因式分解?
完整的消息是这样的:
LAPACK error: the leading minor of order XX is not positive definite,
the factorization could not be completed for dpotf2/dpotrf in
sba_Axb_Chol()。
这意味着增广的法方程的基于Cholesky的算子在某次迭代时出错。理论上,待解决的系统矩阵应该是正定的,这样Cholesky是有效的。然而由于数值误差,并不完全是这样的,并且这时Cholesky也无法因式分解。尽管如此,不会有什么损害,因为当一次迭代出错时,法方程的阻尼增加了,所以在接下去的迭代中它们的矩阵式正定的。换言之,这些错误不会影响收敛。为了阻止sba报错,注释掉sba_levmar.c中的对sba_Axb_Chol()的调用,而去掉sba_Axb_LU()的注释。这样我们就能够使用LU分解来取代Choleskyl来解法方程,并且可以避免警告。然而,注意,LU分解需要更长时间计算,所以以上更改会使sba运行的稍慢一些。
Q20 -- 为什么sba返回错误代码7(用户错误)?
这个错误在sba函数探测到用户生成的预测投影的一个或多个无效的(即,NaN 或者Inf)值返回。如果你使用自己的投影函数,那么就要保证他们被正确的编码了。对于投影函数,包括sba的演示程序,一般是由于对特定点的无效的初始估计;然而,它也可能是因为错误的初始相机参数。为了将引起问题的投影打印在屏幕上,重新运行eucsbademo,使verbosity level为2或者更高。这可以通过设置 eucsbademo.c中的verbose变量为2,然后重新编译来达到。
Q21 -- 演示程序解决哪些类型的光束法平差问题?
如Q7中所述,sba在光束法平差的参数化选择方面非常灵活。为了向用户展示几何光束法平差,demo目录包含了educsbademo程序。升级到1.3版本之前,eucsbademo只支持所有图像的相机本征参数相同的并且在光束法平差过程中保持不变的情况。从版本1.3开始,eucsbademo也支持图像的相机本征参数不同的并且在光束法平差过程中变化的情况。
Q22 -- 怎样更改本征参数的个数并在演示程序过程中保持不变?
eucsbademo程序支持BA的多种的相机本征参数,每个相机都不同(见Q21)。Eucsbademo支持不同数量的本征参数,并且在BA过程中保持不变。如:歪曲率保持不变,纵横比和歪曲率保持不变,纵横比、歪曲率和主点保持不变,更多细节可以在sba_driver()中的第一行找到。
Q23 -- 演示程序的输出在哪里?
一般情况下演示程序不产生输出;只有关于最小化的一些统计资料会被打印出来。为了在BA之后打印运动和/或结构参数到stdout,请编辑eucsbademo.c中的函数sba_driver(),并且去掉对prnt变量赋值的注释,将prnt赋值为BA_MOTSTRUCT, BA_MOT 或者 BA_STRUCT。
Q24 -- 演示程序中的协定坐标系统是什么?
演示程序假设一个左手相机坐标系统,Z轴与相机光轴方向一致,并且指向场景。另一个左手系是世界坐标系统。请参考这里和这里观看图示。
Q25 -- 在哪里可以找到更多关于四元数的信息?
Eucsbademo演示程序包括sba使用四元数来表示旋转。更多关于四元数和旋转的细节可以在Berthold Horn的笔记中找到。
Q26 -- 如何计算图像投影的协方差?
一个图像点的协方差只能够近似的计算;最常见的做法是使用图像深度的空间派生物。更多细节在这里given by Brooks et al. in What value covariance information in estimating vision parameters?, ICCV01, vol. I, pp. 302-308, Vancouver, IEEE Press, 2001.
本文全部译自http://www.ics.forth.gr/~lourakis/sba/faq.html,关于MATLAB中使用sba的四个问题不甚理解,因此未作翻译,见原文
转载地址:http://blog.csdn.net/zhxiya2008/article/details/5772947