目录

  • 一、鱼眼矫正原理讲解
  • 1. 像素坐标转化为相机坐标
  • 2. 无畸变相机坐标 与 畸变后相机坐标 的 对应关系



参考资料:

链接:https://pan.baidu.com/s/19BK9HbRBYtFCjdR0qSIv2Q 
提取码:eu2s

根据前面两篇文章,我们已经知道鱼眼矫正最重要的函数是fisheye::initUndistortRectifyMap(),它能得到map1矩阵,其作用是:

map1是一个2通道矩阵,它在(i, j)处的二维向量元素(u, v) = (map1(i, j)[0], map1(i, j)[1])的意义如下:
将畸变图像中(u, v) = (map1(i, j)[0], map1(i, j)[1])的元素,复制到(i, j)处,就得到了无畸变图像。

那么,fisheye::initUndistortRectifyMap()是如何根据(i, j)算出(u, v)的呢?

OpenCV官方给出了如下公式:

python opencv鱼眼相机去畸变 鱼眼图像畸变校正_fish

其中,(i, j)是无畸变图的像素坐标,而式①中的(i, j, 1)(i, j)的齐次坐标;

式①的iR是相机内参

而最后式⑦中的(u, v),就是无畸变图中(i, j)位置对应的畸变图中的点(u, v)


下面对以上公示做详细介绍。

一、鱼眼矫正原理讲解

1. 像素坐标转化为相机坐标

在阅读本节前,请先学习世界坐标系、相机坐标系、图像坐标系、像素坐标系之间的转换关系,本节认为读者已掌握基础知识。

首先,我们知道相机坐标系像素坐标系的转化关系如下:



python opencv鱼眼相机去畸变 鱼眼图像畸变校正_opencv_02


注:

下面统一将“现实三维世界中的点在相机坐标系下的坐标”简写做“相机坐标”;将“二维图片中的像素坐标系下的坐标”简写作“像素坐标”。

在上述式①中,iR是内参矩阵的逆,则可式①得到的[Xc, Yc, Zc],实际上是真正的相机坐标的归一化坐标,即:



python opencv鱼眼相机去畸变 鱼眼图像畸变校正_像素点_03


然而,我们用[Xc, Yc, Zc],只是用到了它们之间的比例关系。因此,到底是否经过了归一化,其实并不重要,因为比例关系都一样。

至此,我们根据无畸变图中的像素坐标(i, j),得到了它在无畸变条件下,本应该对应的归一化相机坐标(Xc, Yc, Zc)

2. 无畸变相机坐标 与 畸变后相机坐标 的 对应关系

假设现实世界中一点(x, y, z)在相机坐标系下的位置如下图所示,那么,根据上式②③④,我们得到的theta = atan(r)实际上就是入射角,即 点(x, y, z)与相机中心的连线相机光轴(Z轴) 的夹角。如下:



python opencv鱼眼相机去畸变 鱼眼图像畸变校正_opencv_04


图中,左下角的theta1atan(r)计算得来,而右边的theta2点(x, y, z)的入射角,它与左下角的theta1角度相等。

有的读者会问,图中标注的是真正的相机坐标,而我们上面式子中的是归一化后的相机坐标,算出来的theta能一样吗?答案是肯定的。观察发现,我们用到的只是x、y、z之间的比例关系,而不管归一化与否,它们的比例关系都是一样的。

至此,不论是像素坐标(i, j),还是相机坐标(x, y, z),亦或是入射角theta = theta1 = theta2,我们计算的都是无畸变情况下的值。

然后,下一步将是无畸变与畸变的分界点!


根据Juho KannalaSami S. Brandt的大作 《A Generic Camera Model and Calibration Method for Conventional, Wide-Angle, and Fish-Eye Lenses》,我们可以由无畸变入射角theta,配合畸变系数,得到畸变后的r!为了将这个r无畸变时的r区分,我们把这个畸变后的r记作r_d(d表示畸变)。

python opencv鱼眼相机去畸变 鱼眼图像畸变校正_归一化_05

即,r_d = k1 · theta + k2 · theta ^ 3 + k3 · theta ^ 5 + k4 · theta ^ 7 + k5 · theta ^ 9

这也就是式⑤。

至此,我们就得到了畸变情况下的r_d。

畸变点的意义如下所示:

python opencv鱼眼相机去畸变 鱼眼图像畸变校正_opencv_06

在无畸变情况下,上图中,无畸变图中的黑色像素点,应该由现实世界中黑色的无畸变点投影而来;

但是,在鱼眼畸变情况下,上图中,无畸变图中的黑色像素点,应该对应着现实世界中的红色点投影而来。

那么,我们只要找到红色点在畸变图中的位置,然后把它放到黑色无畸变像素点的位置就可以了。

现在,我们能得到红色点对应的r_d,以及黑色点对应的r,那么,令比例因子scale = r_d / r,那么scale · a就应该是红色点在x方向的相机坐标,scale · b就应该是红色点在y方向的相机坐标。

得到了红色点的相机坐标,再根据像素坐标 = 内参 x 相机坐标,就能得到现实世界中红色点对应的畸变图像中的像素坐标,即式⑦。如下:

python opencv鱼眼相机去畸变 鱼眼图像畸变校正_fish_07


**至此,我们就从最开始的无畸变图中的像素点(i, j),经过一路推导,推算到了它对应的畸变图中的像素点(u, v),只要把(u, v)像素复制到(i, j)处,就能得到矫正后的图像。

注:

其实博主对于比例因子scale的原理和作用并不是很清楚,至于为什么 “scale · a就应该是红色点在x方向的相机坐标、而scale · b就应该是红色点在y方向的相机坐标” 也没太搞明白。但这一定是有原理可循的,也希望看到这里的读者能在评论区答疑解惑。