4. 根据特征点匹配关系,估计每幅图像的相机参数(投影矩阵K,旋转矩阵R)


 

 矩阵K与矩阵R都是3×3的矩阵。

CameraParams的定义如下,

我们的目的就是要求出参数R,K,focal(焦距)。

就这行代码,把图片的feature,以及 两两图片之间的关系 pairwise_matches,相机vector传进去,将所有信息存储在cameras中。

下一步。来分析 estimator的源码。

首先求每幅图片的焦距,estimateFocal的代码就不展开看了,因为全是数学公式,看不懂。。

接下来,根据任意两幅图的pairwise_matches中的匹配点数,以两幅图为点,匹配数为边的权值,求解最大生成树。

并且得到树的中心。

我们来看一下findMaxSpanningTree 最大生成树的实现代码。

这个过程大致为:

首先我们得建图,也就是把所有的任意两幅图的点,权值,放入图中。

用并查集算法跑最大生成树,把所有生成树上的边保留下来。并找出树上的所有叶子节点(度为1的点)。

以任意一个叶子结点为根节点,进行bfs遍历,求出这个节点到达其他节点的距离。

并更新max_dists这个数组。

最后找出一个点,这个点到其他点的最大距离最小,也就是这棵树的中心位置当树根。

最后以这个点为根,再跑一遍bfs,这一遍就是求出每一个节点(图片)的K,R参数。

可以看一下

span_tree.walkBreadthFirst(span_tree_centers[0], CalcRotation(num_images, pairwise_matches, cameras));

 

主要 重载的(),这一个地方在后面bfs的时候会用到。但是按照论文中给的公式以及代码

 

我们是无法推出 最终的R的。但是推一下可以发现 cameras[edge.to].R 保存的是R1的逆

推一下试试看:

我们要求的是R1,但是代码中给出的是K_from_inv * H_inv * K_to, 但是from应该是2.

所以我们给R1取逆才可以。 得到R1_inv = R2_inv * K2 _inv * H1,2_inv *K1

可以发现K2 _inv * H1,2_inv *K1 正好是Mat R = K_from.inv() * pairwise_matches[pair_idx].H.inv() * K_to;

而下面求cameras[edge.to].R的时候 需要前面用cameras[edge.from].R 来 乘 R

而我们推出的公式中 确实是用 R2_inv 来推出的 R,所以每次都是 R_inv 来求解下一个R_inv。

后面的bfs也没什么难得了。常规的代码。

不过值得学习的是,这个地方对第二个参数做了 泛型处理,并且把类的写法都标准化,就可以省很多事情。

5. 捆绑调整求精相机参数


这一块代码就是对cameras内的参数进行求精,我们来看一下如何参数求精的。

直接看这一块代码即可

这块函数的源码如下,对主要部分进行注释,里面太多数学公式表示看不懂:

最后。求相机的焦距,就是排序,然后搞一下就可以了。

 

 

 

 

 

 

 

 

opencv-stitching_detailed源码剖析(1)

     这个源码的主要目的就是输入无序的图像,输出全景图。                                        注:学习过程参照GXY学长整理的文档和网络博客。      1...

阅读全文

欢迎留言

*