PMVS论文随笔(1)

博客园排版系统真的比较挫,能够访问个人github.io阅读git

关于Unit的概念

在pmvs的源代码中,有一个函数是getUnit ,其函数以下(在PMVS2的windows版本代码,optim.cc文件,1184行):github

float Coptim::getUnit(const int index, const Vec4f& coord) const {
  const float fz = norm(coord - m_fm.m_pss.m_photos[index].m_center);
  const float ftmp = m_ipscales[index];
  if (ftmp == 0.0)
    return 1.0;

  return 2.0 * fz * (0x0001 << m_fm.m_level) / ftmp;
}

其中index是图像编号,coord是三维射影空间下的坐标。windows

这个函数在pmvs代码中几乎全部的和空间几何计算相关的函数中均被调用,最开始看代码时我并无特别注意,可是随着代码阅读的深刻,发现若是不将该函数读懂,就彻底没法理解pmvs中全部的几何计算函数到底是在作什么,因而今天花时间特地钻研了下,把该函数的含义表达清楚。app

先说结论:该函数是计算将图片上的一个像素反投影到空间的一个指定的面片(patch)上获得的正方形的大小(以世界坐标系中的距离为量度),这个面片知足以下条件——面片的中心位于coord, 面片的法线与相片的法线平行但方向相反(也就是论文中初始化patch时的法线计算方法)。函数

这个结论看起来很是复杂,简单说就是若是我在空间的某个坐标处想要画一个正方形,使得该正方形投影到对应的与该正方形平行的相片上的大小刚好是1×1像素大小,那么这个正方形的边长在世界坐标系中的表达到底是多少。这个函数就是来求解这个边长的。spa

这样的话这个函数做用其实就至关大了,他直接沟通了像素坐标和空间坐标的比例关系,能够粗略的比较相片对于场景的缩放,简化不少投影和反投影计算。而这个函数用到的计算方法其实也很是简单。就是简单的类似三角形关系,具体解释以下code

小孔成像相机的几何关系以下图所示(摘自《 Multiple View Geometry in Computer Vision 》)orm

小孔成像相机的几何关系

从该成像原理上咱们能够看出,空间中一个长度为\(D\) 的物体投影到图像上长度\(l\)知足以下关系:
\[ \frac{D}{l} = \frac{Z_0}{f} \]
其中\(f\) 为焦距,\(Z_0\) 为物体到摄影中心的距离。
由上式能够获得:
\[ D = \frac{l}{f}Z_0 \]
这样咱们已知\(l\) 为1个像素长度,\(Z_0\) 能够直接由coord到相片的摄影中心直接计算获得。那么只要咱们知道以像素为单位的\(f\)的数值,就能够直接获得\(D\)。幸运的是,根据通常CCD相机内参数矩阵中各变量的定义:
\[ K=\begin{bmatrix} a_x & s & x_0 \\ 0 & a_y & y_0 \\ 0 & 0 & 1 \end{bmatrix} \]
其中\(a_x\)\(a_y\)分别是相机在x和y方向上的焦距,且以像素为量纲。另一般状况下,CCD相机在x和y方向上的比例所以近似相等,即\(a_x \approx a_y\),这样咱们能够用下式来近似计算\(f\)
\[ f = \frac{a_x + a_y}{2} \]
综上可得:
\[ D=\frac{2}{a_x + a_y} Z_0 \]
这就是pmvs中getUnit的计算方法, 特别解释下,代码中m_ipscales[index]就是提早计算好的\(a_x+a_y\)的数值,而(0x0001 << m_fm.m_level)则是一个比例因子,可让程序将图像缩放到一半或者四分之一大小进行计算。blog

相关文章
相关标签/搜索