@ 《视觉SLAM十四讲》知识点与习题

《视觉SLAM十四讲》第五讲知识点整理+习题

正在学习SLAM相关知识,将一些关键点及时记录下来。

知识点整理

本讲主要讨论了相机模型,描述投影关系,讲解相机内参和外参

  1. 相机的针孔模型:需要了解焦距(物理成像平面到小孔的距离)、光心(针孔模型中的小孔)、物理成像平面和像素平面
    像素坐标系与成像平面之间,相差了一个缩放和原点平移:x轴缩放α,y轴缩放β,原点平移[cx, cy]^T
  2. 相机的内参:K。常认为相机的内参在出场之后是固定的,不会在使用过程中发生变化
  3. 相机的外参:R, t。由于相机在运动,所以外参应该是他的世界坐标系根据相机的当前位姿变换到相机坐标系下的结果。外参会随着相机运动发生改变
  4. 透镜的畸变模型
  5. 径向畸变:由透镜自身的形状引起的畸变。越靠近图像的边缘,这种现象越明显。径向畸变包括桶形畸变和枕形畸变。在这两种畸变中,穿过图像中心和光轴有交点的直线还能保持形状不变
    1. 桶形畸变是由于图像放大率随着与光轴之间的距离的增加而减少
    2. 枕形畸变则恰好相反
      用与距中心的距离有关的二次及高次多项式函数进行纠正。对于畸变较小的图像中心区域,主要是k1起作用; 对于畸变较大的边缘区域,主要是k2起作用;对于鱼眼镜头等畸变很大的摄像头,可以加入k3进行纠正
  6. 切向畸变:是由于在相机的组装过程中由于不能使透镜和成像面严格平行引起的。
    在极坐标系中,径向畸变认为是坐标点沿着长度方向发生了变化,切向畸变认为是水平夹角发生了变化。
    用下图中的公式,分别对x,y的畸变进行纠正。其中k1,k2,k3进行的是径向畸变的纠正,p1, p2进行的是切向畸变的纠正
  7. 基线:左右相机之间的距离
  8. 双目相机:通过同步采集左右相机的图像,计算图像间视差,来估计每一个像素的深度。其中,视差是指左右图的横坐标之差。视差越大,距离越近。同时,由于视差最小为1个像素,于是双目的深度存在一个理论上的最大值,由fb确认。且,当基线越长时,双目能测到的最大距离就会越远。
    但是视差d本身的计算比较困难,因为需要确切知道同一个点在左右图中的对应关系。当想计算每个像素的深度时,其计算量与精度都称为问题,而且只有在图像纹理变化丰富的地方才能计算视差
  9. RGB-D相机模型:按原理可以分为两类。
    1. 第一类是通过红外结构光(Structured Light)来测量像素距离
    2. 第二种是通过飞行时间法(ToF)原理测量像素距离,可以获得整个图像的像素深度
      无论是哪一种RGB-D相机都需要向探测目标发射一束光线,相机根据返回的结构光图案,计算物体与自身之间的距离。
      在测量深度之后,RGB-D相机通常按照生产时的各相机摆放位置,自己完成深度与彩色图像素之间的配对,输出一一对应的彩色图和深度图,因此可以在同一图像位置,读取到色彩和距离信息,计算像素的3D相机坐标,生成点云。
      对于RGB-D数据,既可以在图像层面进行处理,还可以在点云层面处理
      RGB-D相机能够实时的测量每个像素点的距离,但是由于这种发射-接收的测量方式,其适用范围比较受限。不能在室外使用,同时使用多个时也会相互干扰。对于透射材质的物体,因为接收不到反射光,所以无法测量这些点的距离
  10. 图像:这里需要注意的点是:在图像中,数组的行数对应图像的高度,列数对应图像的宽度。平时说的图像的宽度或列数对应着X轴,而图像的行数或高度对应着Y轴
    unsigned char pixel = image[y][x];
    
  11. 一般,图像灰度使用unsigned char表示8位整数记录;各个像素与相机的距离使用unsigned short 0-65536表示

OpenCV实践

  1. 图片基础

    1. 注意对位于x,y处的像素的访问。所以可以得到,对于每一个像素点,它们的多通道值是连续存储的

       for ( size_t y=0; y<image.rows; y++ ){// 用cv::Mat::ptr获得图像的行指针unsigned char* row_ptr = image.ptr<unsigned char> ( y );  // row_ptr是第y行的头指针for ( size_t x=0; x<image.cols; x++ ){// 访问位于 x,y 处的像素unsigned char* data_ptr = &row_ptr[ x*image.channels() ]; // data_ptr 指向待访问的像素数据// 输出该像素的每个通道,如果是灰度图就只有一个通道for ( int c = 0; c != image.channels(); c++ ){unsigned char data = data_ptr[c]; // data为I(x,y)第c个通道的值}}
      }
      

PCL实践

  1. 安装PCL点云库

    1. 因为先前已经安装了OpenCV和ROS,所以很多依赖不需要重复安装了
      安装sudo apt-get install libopenni-dev
      sudo apt-get install libopenni2-dev
  2. 从PCL的github上的release目录下,网址为1。 通过git clone方式下载下来
  3. mkdir build然后进入build目录,进行cmake和make操作即可。注意,PCL库的make过程比较漫长,如果卡了,可以尝试关闭当前terminal,重新make一下
  4. 下面进入了编译joinMap的工作。同3操作,不过最后运行时,需要在包含pose.txt的目录下运行,所以,输入指令为
    ./build/joinMap
    

    此时会显示下述文字,同时在当前目录下生成一个map.pcd文件

    这是使用cloud_viewer显示的map.pcd影像,是可以进行任意角度旋转的

  5. 源码分析:从源码中可以获得对于深度图、彩色图等更多相关的知识点
    1.  for ( int i=0; i<5; i++ ){boost::format fmt( "./%s/%d.%s" ); //图像文件格式colorImgs.push_back( cv::imread( (fmt%"color"%(i+1)%"png").str() ));depthImgs.push_back( cv::imread( (fmt%"depth"%(i+1)%"pgm").str(), -1 )); // 使用-1读取原始图像double data[7] = {0};for ( auto& d:data )fin>>d;Eigen::Quaterniond q( data[6], data[3], data[4], data[5] );Eigen::Isometry3d T(q);T.pretranslate( Eigen::Vector3d( data[0], data[1], data[2] ));poses.push_back( T );}
      

    从上述代码可以知道,位姿记录格式为x, y, z, rx, ry, rx, w格式,其中x, y, z表示平移, rx, ry, rx, w表示四元数,其中w表示四元数的实数部分

    1.      // 计算点云并拼接// 相机内参 double cx = 325.5;double cy = 253.5;double fx = 518.0;double fy = 519.0;double depthScale = 1000.0;
      

      其中,固定了depthScale表明样例中给定的图片的深度尺度已知

    2.  cv::Mat color = colorImgs[i]; cv::Mat depth = depthImgs[i];Eigen::Isometry3d T = poses[i];for ( int v=0; v<color.rows; v++ )for ( int u=0; u<color.cols; u++ ){unsigned int d = depth.ptr<unsigned short> ( v )[u]; // 深度值if ( d==0 ) continue; // 为0表示没有测量到Eigen::Vector3d point; point[2] = double(d)/depthScale; point[0] = (u-cx)*point[2]/fx;point[1] = (v-cy)*point[2]/fy; Eigen::Vector3d pointWorld = T*point;PointT p ;p.x = pointWorld[0];p.y = pointWorld[1];p.z = pointWorld[2];p.b = color.data[ v*color.step+u*color.channels() ];p.g = color.data[ v*color.step+u*color.channels()+1 ];p.r = color.data[ v*color.step+u*color.channels()+2 ];pointCloud->points.push_back( p );}
      

      其中,对color和depth的每一个元素同时进行遍历,就暗含了“相机已经将彩色图和深度图一一对应”
      对于u,v是指图片上的像素位置,表示像素空间
      Eigen::Vector3d point表示对应像素点在相机坐标系中的位置
      根据书本P60的公式,**相机位姿T(即相机坐标系在世界坐标系中的表示)**左乘当前点在相机中的坐标,等于当前点在世界坐标系中的坐标。p_w=T_w_c p_c

习题

  1. 由于暂时使用的是开源数据集,后续才开始实时采集,暂时不进行相机标定,后续用到了再来补充

视觉SLAM十四讲——第五讲相机与图像相关推荐

  1. 《视觉slam十四讲》ch5相机与图像学习笔记(3)——实践部分 RGB-D相机代码解释及相关函数介绍

    在这篇博客中,主要介绍<视觉SLAM十四讲>第五讲的实践部分--RGB-D代码详解.关于imageBasics的代码可见我另一篇博客: <视觉slam十四讲>ch5学习笔记(1 ...

  2. 《视觉slam十四讲》ch5相机与图像学习笔记(1)—— 实践部分imageBasics代码讲解

    第五章的ch5/imageBasics例程相对来说比较简单,代码内容包括读取图像文件,输出图像信息,遍历图像,图像的直接复制以及利用clon函数复制等.介绍一下其中的干货. 目录 1.关于int ma ...

  3. 视觉SLAM十四讲学习笔记-第四讲---第五讲学习笔记总结---李群和李代数、相机

    第四讲---第五讲学习笔记如下: 视觉SLAM十四讲学习笔记-第四讲-李群与李代数基础和定义.指数和对数映射_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第四讲-李代数求导与扰动模 ...

  4. 视觉SLAM十四讲学习笔记-第五讲-相机模型

    专栏系列文章如下: 视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习 ...

  5. 视觉SLAM十四讲笔记-第五讲 相机与图像

    目录 Ⅰ.单目相机模型 一.针孔相机模型及公式推导 二.畸变模型 三.成像过程 Ⅱ.双目相机模型 Ⅲ.RGB-D 相机模型 Ⅳ.计算机中图像的表示 Ⅴ.牛刀小试-代码实践 一.读取图像数据(灰度图为例 ...

  6. 《视觉SLAM 十四讲》第五讲 实践:拼接点云-编译遇到的terminate called after throwing an instance of 'pcl::IOException问题及解决方法

    <视觉SLAM 十四讲>第五讲 实践:拼接点云-编译遇到的terminate called after throwing an instance of 'pcl::IOException问 ...

  7. 视觉SLAM十四讲学习记录 第五讲

    之前第四讲的地址 以及第四讲习题的地址 第五讲 相机与图像   前面两讲中,我们介绍了"机器人如何表示自身位姿"的问题,部分地解释了SLAM经典模型中变量的含义和运动方程部分.本讲 ...

  8. 《视觉SLAM十四讲》学习笔记:第5讲相机与图像

    <视觉SLAM十四讲>学习笔记:第5讲相机与图像 前言:本学习笔记将记录<视觉SLAM十四将>中一些重要的知识点,并对书中一些比较难的知识点添加上一些笔者个人的理解,以供笔者本 ...

  9. 视觉SLAM十四讲 第5讲 相机与图像

    视觉SLAM十四讲 第5讲 相机与图像 1. 关于针孔相机模型 2. 关于图像畸变 2.1 什么是畸变 2.2 畸变参数 2.3 关于双目相机模型 三维世界中的一个物体反射或发出的光线,穿过相机光心后 ...

  10. 视觉SLAM十四讲学习笔记-第七讲-视觉里程计-三角测量和实践

     专栏汇总 视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第 ...

最新文章

  1. html追加行clone,调用clone()方法后就可以将复制的节点追加到body元素内。( ) 答案:√...
  2. Java - 初识Java
  3. 10分钟带你探索css中更为奇妙的奥秘
  4. 前端学习(981):jquery入门
  5. php ip2long mysql,PHP基于ip2long实现IP转换整形
  6. php冒泡 插入选择 排序,说说PHP数组的三种排序(冒泡/选择/插入)方法
  7. linux脚本制定java堆大小_Java使用比堆大小更多的内存(或正确的Docker内存限制大小)...
  8. 通达信公式转python为什么很难_转行数据分析为什么这么难?
  9. hash算法_Hash 一致性算法的 Java 实现
  10. 互联网平台掘金三四五线城市,你需要知道的9.9个真相
  11. 此博客更新较慢,主要用于微信公众号“申龙斌的程序人生”的备份了
  12. python键盘控制_python如何直接控制鼠标键盘
  13. 【操作系统 - 1】先来先服务FCFS和短作业优先SJF进程调度算法
  14. 基于禁忌搜索优化的VRP问题求解matlab仿真
  15. 李峋同款爱心代码-电视剧《点燃我温暖你》
  16. 【本周Python热点回顾】画一棵漂亮的樱花树,Python3*和**运算符,Python入门,这就是Python3.8么,i了
  17. characterReplacement-替换后的的最长重复字符
  18. 搞笑趣味短信-人生有什么追求
  19. egret制作小游戏:数字华容道及有解判断(代码注释)(评论区有源码下载~)
  20. vue使用腾讯地图(拾取坐标)

热门文章

  1. 2021-07-13Python——报错 UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xce in position 52: invali
  2. 上传视频 获取视频第一帧 做为封面 前端js
  3. ImageView静态设置参数
  4. 【C】Malloc与结构体,其实就是C语言里面的new和类
  5. 哪些因素会影响工控机的正常运行?
  6. 计算机网络通信行业职业分析
  7. 北京野趣水库烧烤好去处882
  8. C++头文件【iomanip】的简要讲解
  9. 【十五】Java网络编程(能实现计算机自娱自乐的网络编程)
  10. 魔方 Unity3D】使用Unity3D实现魔方游戏