您当前的位置: 首页 > 
  • 2浏览

    0关注

    417博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

(01)ORB-SLAM2源码无死角解析-(12)图像、特征点、关键点去畸变

江南才尽,年少无知! 发布时间:2022-03-16 17:39:09 ,浏览量:2

讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解的(01)ORB-SLAM2源码无死角解析链接如下(本文内容来自计算机视觉life ORB-SLAM2 课程课件): (01)ORB-SLAM2源码无死角解析-(00)目录_最新无死角讲解:https://blog.csdn.net/weixin_43013761/article/details/123092196   文末正下方中心提供了本人 联系方式, 点击本人照片即可显示 W X → 官方认证 {\color{blue}{文末正下方中心}提供了本人 \color{red} 联系方式,\color{blue}点击本人照片即可显示WX→官方认证} 文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证  

一、前言

在上一篇博客的末尾我们提到,src/Frame.cc 的初始化函数除了完成 ORB 特征提取之外,还完成了一些其他的操作。比如我们该篇博客需要讲的特征点去畸变。

 

二、理论介绍

相机透镜在制造的时候,由于精度以及组装工艺的偏差会引入畸变,导致原始图像的失真,拍摄出来的图像并非是理论上的理想图像。镜头的畸变分为径向畸变和切向畸变两类。   径向畸变 \color{blue}{径向畸变} 径向畸变:顾名思义,径向畸变就是沿着透镜半径方向分布的畸变,产生原因是光线在远离透镜中心的地方比靠近中心的地方更加弯曲。这种畸变在短焦镜头中表现更加明显,径向畸变主要包括桶形畸变和枕形畸变两种。以下分别是枕形和桶形畸变示意图: 在这里插入图片描述 成像仪光轴中心的成像仪光轴中心的畸变为0,沿着镜头半径方向向边缘移动,畸变越来越严重。畸变的数学模型可以用主点(principle point)周围的泰勒级数展开式的前几项进行描述,通常使用前两项,即k1和k2,对于畸变很大的镜头,如鱼眼镜头,可以增加使用第三项k3来进行描述,成像仪上某点根据其在径向方向上的分布位置,调节公式为: x 0 = x ( 1 + k r 2 + k r 4 + k r 6 ) \color{blue} x_0=x(1+kr^2 +kr^4+kr^6) x0​=x(1+kr2+kr4+kr6) y 0 = y ( 1 + k r 2 + k r 4 + k r 6 ) \color{blue} y_0=y(1+kr^2 +kr^4+kr^6) y0​=y(1+kr2+kr4+kr6)公式里 ( x 0 , y 0 ) (x0,y0) (x0,y0)是畸变点在成像仪上的原始位置, ( x , y ) (x,y) (x,y)是校正后新的位置。下图是距离光心不同距离上的点经过透镜径向畸变后点位的偏移示意图,可以看到,距离光心越远,径向位移越大,表示畸变也越大,在光心附近,几乎没有偏移。 在这里插入图片描述

  切向畸变 \color{blue}{切向畸变} 切向畸变:由于透镜本身与相机传感器平面(成像平面)或图像平面不平行而产生的,这种情况多是由于透镜被粘贴到镜头模组上的安装偏差导致。那么什么是切线畸变呢?如下图为切向畸变的一个示例: 在这里插入图片描述 上图显示某个透镜的切向畸变示意图,大体上畸变位移相对于左下——右上角的连线是对称的,说明该镜头在垂直于该方向上有一个旋转角度。可以明显看到围绕透镜中心的,都已经不是圆形了,可是这个为什么叫切线位置呢?我们再来看下图:

在这里插入图片描述 这样径向畸变与切向畸变形成对比,大家应该就知道了,可以看到与径向畸变类似,离透镜中心越远则畸变越严重。如果理想位置沿着45°度直径径,向两边的切线畸变,距离越远,畸变越严重,则形成了上面的椭圆图像。切向畸变可以用两个额外的参数 p 1 p1 p1 和 p 2 p2 p2 来描述: x 0 = x + [ 2 p 1 y + p 2 ( r 2 + 2 x 2 ) ] \color{blue} x_0=x+[2p_1y+p_2(r^2+2x^2)] x0​=x+[2p1​y+p2​(r2+2x2)] y 0 = y + [ 2 p 2 x + p 1 ( r 2 + 2 y 2 ) ] \color{blue} y_0=y+[2p_2x+p_1(r^2+2y^2)] y0​=y+[2p2​x+p1​(r2+2y2)] 该公式的具体又来,在该章节我们就步进行详细的讲解了。   总结 \color{blue}{总结} 总结: 同时对径向、切向畸变消除就是将两组式子合并。最终可以得到5个畸变参数,畸变参数的一般顺序是 k 1 , k 2 , p 1 , p 2 , k 3 k1,k2,p1,p2,k3 k1,k2,p1,p2,k3。之所以把 k 3 k3 k3 放在最后其实也很容易理解,因为前面说了一般 k 1 , k 2 k1,k2 k1,k2 用来处理径向畸变足矣, k 3 k3 k3 相对而言用的比较少。

大家要注意一点的是上面的给出的公式是畸变的过程,那么也就是说 x 0 , y 0 x_0,y_0 x0​,y0​ 为畸变之后的坐标, x , y x,y x,y 才是没有畸变的坐标。我们做畸变矫正,是需要反过来的,也就是已知 x 0 , y 0 x_0,y_0 x0​,y0​,求解 x , y x,y x,y。其具体的推到过程,这里就不进行讲解了,因为在 opecv 中存在函数 cv::undistortPoints(),其可以直接进行矫正。

下面是图像畸变矫正的结果对比(图片矫正就是对每个像素进行畸变矫正); 在这里插入图片描述

 

三、源码注释

src/Frame.cc 文件中的构造函数 Frame::Frame(const Frame &frame) 中,其调用了 UndistortKeyPoints(); 函数,该函数就是对关键点进行矫正的过程,主要核心是调用 opecv 的函数,在求解过程中还需要提供摄像头内参,也就是 Examples/Monocular/TUMx中的如下参数:

//摄像头内参
Camera.fx: 517.306408
Camera.fy: 516.469215
Camera.cx: 318.643040
Camera.cy: 255.313989

//畸变参数
Camera.k1: 0.262383
Camera.k2: -0.953104
Camera.p1: -0.005358
Camera.p2: 0.002628
Camera.k3: 1.163314

关于 UndistortKeyPoints() 的注释如下:

/**
 * @brief 用内参对特征点去畸变,结果报存在mvKeysUn中
 * 
 */
void Frame::UndistortKeyPoints()
{
    // Step 1 如果第一个畸变参数为0,不需要矫正。第一个畸变参数k1是最重要的,一般不为0,为0的话,说明畸变参数都是0
	//变量mDistCoef中存储了opencv指定格式的去畸变参数,格式为:(k1,k2,p1,p2,k3)
    if(mDistCoef.at(0)==0.0)
    {
        mvKeysUn=mvKeys;
        return;
    }


    // Step 2 如果畸变参数不为0,用OpenCV函数进行畸变矫正
    // Fill matrix with points
    // N为提取的特征点数量,为满足OpenCV函数输入要求,将N个特征点保存在N*2的矩阵中
    cv::Mat mat(N,2,CV_32F);
	//遍历每个特征点,并将它们的坐标保存到矩阵中
    for(int i=0; i            
关注
打赏
1592542134
查看更多评论
0.0683s