zoukankan      html  css  js  c++  java
  • 从零开始一起学习SLAM | 你好,点云

    本文提纲

    先热热身
    点云是啥
    你知道点云优缺点吗?
    点云库PCL:开发者的福音
    PCL安装指北
    炒鸡简单的PCL实践
    留个作业再走
    先热热身

    小白:hi,师兄,好久不见
    师兄:师妹好,上周单应矩阵作业做了吗?
    小白:嗯,做了,这个单应矩阵真的挺有意思的。作业之外,我发现了一个新技能。。。
    师兄:什么技能?
    小白:我发现很多网上流传的图片都可以用上次我学过的单应矩阵实现,你看这张图,我第一次看到还以为是真的


    现在知道这不就是我们上节课讲的单应矩阵的变换吗?
    果然我在网上找到了原图


    现在我也会用OpenCV里的单应函数做这样的图了~

    师兄:哈哈,厉害了,会学以致用了。话说回来,今天有啥想问的?
    小白:嗯,最近在看点云相关的,师兄要不给我扫扫盲吧?
    师兄:这个我也有些了解,就把我知道的给你说说吧
    小白:yeah,师兄最棒!

    点云是啥

    师兄:那我就当你是个小白吧,从点云的定义说起。点云的英文是“point cloud”,点云的意思和它的名字一样,就是一堆点的集合,看起来像是一坨“云”。
    小白:一坨。。。

    师兄:哦,一坨不太文雅,应该是像一片“云”一样。上面只是一种形象的说法,其实点云在编程实现的时候是一种数据结构,用来表达多维空间中点的集合,这个多维空间一般对我们来说是三维空间。
    小白:哦,原来如此,也就是我们所在的 XYZ 空间咯

    师兄:对,因此点云在三维相关的领域内用的很多,比如三维扫描,三维重建、三维感知等方面。
    小白:那点云是怎么得到的啊?
    师兄:一般是通过三维成像传感器得到的,比如双目相机、三维扫描仪、RGB-D相机等,除了可以用这种特殊的硬件得到,也可以用计算机合成。

    小白:嗯嗯,师兄说了这么多,还是没有一个直观的印象,这个点云到底长什么样?
    师兄:想要直观一点的话,我直接给你看点云图吧,你看下面就是室外一个街道的点云图,远看能看清房子,树木的轮廓啊


    小白:嗯嗯,确实能看出轮廓出来,不过不像是我们平时拍的照片,这个点云好像看着不是很清楚哎!

    你知道点云优缺点吗?

    师兄:确实是这样的,这也是点云的一个缺点吧
    小白:那师兄能否顺便说说,这个点云的表达有啥优缺点呢?
    师兄:这个问题问的有水平,额,我想想,我先说说优点吧。

    第一个优点就是可以表达物体的空间轮廓和具体位置,比如上面这个图,我们能看出来街道的样子,房屋的形状,距离摄像机的距离也是知道的。

    第二个优点我觉得就是,点云本身和视角无关,也就是你可以任意旋转,可以从不同角度和方向观察一个点云,而且不同的点云只要在同一个坐标系下就可以直接融合,还是很方便的。

    至于缺点嘛,我们先来放大一下点云看看。如下图所示,如果拉近一直放大最后看到的就是一个个的点。也就是空间中成千上万的点组成了一个点的集合,他们构成了上面的街道房屋等。


    小白:这个点云放大了啥都看不出来啊
    师兄:对,这个是点云的其中一个缺点,那我想想点云还有哪些缺点哈!

    第一个缺点就是点云并不是稠密的表达,一般比较稀疏,你放大了看,会看到一个个孤立的点。它的周围是黑的,也就是没有信息。所以在空间很多位置其实没有点云,这部分的信息是缺失的。

    第二个缺点嘛,就是点云的分辨率和离相机的距离有关。你离近了看是看不清是个什么东西的,只能拉的很远才能看个大概。

    点云库PCL:开发者的福音

    小白:嗯,了解了,好像缺点也没啥影响哈。再问个问题,那这些点云怎么显示和保存啊,感觉点云很多的话,好像很复杂的样子。。。

    师兄:的确,比如一张 640 x 480 尺寸的深度图就可以转换为拥有三十万个空间点的点云,大的点云可能有百万千万以上,不过,不用担心,有一个开源的点云库,英文名为Point Cloud Library ,简称PCL ,专门用来进行点云的读写,处理等各种操作。

    小白:那太好了,这个PCL是谁做的啊?好用吗?
    师兄:这个PCL是由一大批世界范围内的名校和科技公司合作开发的,你看下面是他们的名字


    小白:哇塞,好多不认识啊!不过我看到了ETH,也就是苏黎世联邦理工大学,还有TUM,也就是德国慕尼黑工业大学,我看论文经常看到他们学校的,他们都是SLAM领域非常顶级的研究机构呢

    师兄:嗯,看来你论文看了不少啊,哈哈。我们继续说PCL,PCL真的挺方便,支持跨平台,可以在Windows,Linux,macOS,iOS,Android上部署,可以说非常全了,而且PCL可以分为很多小的库文件,在非常适合于计算资源有限或者内存有限的应用场景,非常方便移动端开发。

    小白:那可以说很通用了哈!对了师兄,那这个PCL都有啥功能?
    师兄:功能很丰富了,基本PCL的操作都有,比如读写、滤波、特征估计、表面重建、配准、分割等等,你看这个图就是PCL的功能啦


    小白:嗯嗯,那是不是平时我们操作点云,调PCL的函数就行了?
    师兄:怎么说呢,其实PCL类似于OpenCV那样,有很多功能模块,每个模块里有封装好的函数,你可以调这些函数进行基本处理,但是有些功能PCL里可能没有,这时候需要自己写一些代码实现。
    小白:嗯,师兄,总之就是要多编程实践啦

    PCL安装指北

    师兄:对,那我们开始实践环节吧,带着你做一些PCL的基础编程实现
    小白:太好啦!

    师兄:首先,我们先来看看点云库,也就是PCL的安装方法,推荐用Linux环节哈,安装很方便
    小白:嗯,我之前听师兄说Linux环境配置比较简单,就开始学Linux了,确实,比Windows方便多啦,就是刚开始用命令行不太习惯,好多命令记不住。。。

    师兄:没事的,命令行不用刻意去记,忘记了就去查一下,用多了自然知道了
    小白:知道啦!
    师兄:PCL在Linux下安装有两种方式,一种是安装编译好的库,一种是从源码编译。你看这个是PCL GitHub上的安装包,前面几种是不同环境下的编译好的库了,最后的source code就是源码安装


    小白:那这两种方式有什么不一样的?
    师兄:第一种方式比较简单,几行命令就可以搞定,比如如果你用的是Ubuntu 16.04版本的Linux系统的话,只需要打开一个终端,输入
    sudo apt-get install libpcl-dev pcl-tools
    就可以自动安装啦,优点是安装的版本都是稳定版本(当然也比较旧一点),不需要处理依赖关系,安装非常方便,不过这种安装方式也有一些缺点。一个是一般安装的都不是最新的,二是安装的都是别人已经编译好的通用的二进制库,所以不能根据自己的需求进行调整

    小白:只要一行代码确实方便啊!那第二种从源码安装的优缺点呢?
    师兄:第二种从源码编译安装也没有麻烦多少,它是把所有的源代码都下载了下来,所以会占用较多的存储空间。但好处很多,比如可以下载最新的版本或者指定的版本,可以根据自己的需求在编译时进行选择,可以查看甚至修改某个函数的源代码等等

    小白:感觉都挺好,选择恐惧症了,不知道该选哪个了。。。
    师兄:推荐用第二种吧,从源码自己编译安装,更方便一些
    小白:好,具体如何操作呢?
    师兄:首先打开PCL GitHub的网址:https://github.com/PointCloudLibrary/pcl
    然后选择你需要的版本号,如下图所示


    如果没什么特殊需要可以不选择,我们打开一个终端,输入下面一行代码

    git clone https://github.com/PointCloudLibrary/pcl pcl-trunk

    然后PCL 源代码就 clone 到你的电脑上了
    下一步就是Ubuntu下安装的老一套了,进入目录,新建一个build文件夹存放编译的文件,然后进入build文件夹,cmake一下,然后make,最后install,这一系列流程就是下面这段代码了

    cd pcl-trunk && mkdir build && cd build
    cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
    make -j2
    sudo make -j2 install

    静静的等待编译结束就好啦!

    炒鸡简单的PCL实践

    小白:嗯嗯,我照着做一下。。。嗯,编译好啦,我们开始用PCL写代码吧
    师兄:那我们来写一个读取RGB-D相机的一帧图像并用PCL转化为点云的代码吧

    首先,我们需要定义点云的结构,我们这里使用typedef来定义两个常用的类型

    typedef pcl::PointXYZRGB PointT;
    typedef pcl::PointCloud<PointT> PointCloud;
    

     

    这里的 pcl::PointXYZRGB 就是我们定义的空间点,它包括空间坐标XYZ以及颜色信息RGB,此外常用的点的 类型还有

    pcl::PointXYZRGBA ( 多了一个alpha通道), pcl::PointXYZ (只有空间位置,不包含颜色信息),pcl::PointXYZHSV (空间位置 + HSV颜色空间表示的颜色)等,总之,我们这里输入的 RGB-D 图像就定义为pcl::PointXYZRGB。

    小白:师兄,为什么这里要用typedef 啊?我看好多地方都这样写的
    师兄:这样是为了把那么长的一个类型用一个简单的别名 PointT 来代替,不至于代码显得特别冗长

    小白:这样啊,懂了,那么 pcl::PointCloud就是点云了吧?它里面可以包含许多类型为PointT的点
    师兄:对,我们继续。其实RGB-D图像转换为点云的方式也简单,代码如下

    for (int m = 0; m < depth.rows; m++)
        for (int n = 0; n < depth.cols; n++)
        {
            // 获取深度图中(m,n)处的值
            ushort d = depth.ptr<ushort>(m)[n];
            // d 可能没有值,若如此,跳过此点
            if (d == 0)
                continue;
            // d 存在值,则向点云增加一个点
            PointT p;
            // 计算这个点的空间坐标
            p.z = double(d) / camera.scale;
            p.x = (n - camera.cx) * p.z / camera.fx;
            p.y = (m - camera.cy) * p.z / camera.fy;
    
            // 从rgb图像中获取它的颜色
            p.b = rgb.ptr<uchar>(m)[n * 3];
            p.g = rgb.ptr<uchar>(m)[n * 3 + 1];
            p.r = rgb.ptr<uchar>(m)[n * 3 + 2];
    
            // 把p加入到点云中
            cloud->points.push_back(p);
        }
    --------------------- 
    作者:electech6 
    来源:CSDN 
    原文:https://blog.csdn.net/electech6/article/details/84566319 
    版权声明:本文为博主原创文章,转载请附上博文链接!
    

      

    之所以能这样写,前提是 RGB 和 depth图已经对齐了,也就是 depth 图中某个位置的深度值在 RGB图中同样的位置处就是它对应的颜色。
    小白:中间那个计算点的空间坐标好像就是用《从零开始一起学习SLAM | 相机成像模型》的相机成像模型公式的?

    师兄:对,所以这里需要相机内参。然后需要注意的就是OpenCV里 RGB 图像里存储颜色顺序其实是BGR,所以从 RGB中获取颜色时顺序也是 BGR而不是RGB,这里容易错。如果没 问题的话,输出结果如下,可以在终端里用pcl_viewer 查看,用鼠标可以缩放和翻转查看,如果你放大了就发现是一个个的点。下图是离的比较远的结果


    小白:嗯,这个看起来挺不错的,那下一步呢?
    师兄:下一步就是多个点云融合了,这部分我给你变成了作业的形式,你可以自己去编程练习一下,可以利用前面图像生成点云的代码。
    小白:额,好。。师兄猝不及防啊。。。

    留个作业再走

    题目:点云融合实验。已经给定3帧(不连续)RGB-D相机拍摄的 RGB + depth 图像,以及他们之间的变换矩阵(以第一帧为参考帧),请将上述3帧RGB-D图像分别生成点云并融合出最终的点云输出。
    练习目的:熟悉PCL的使用,熟悉RGB-D图像到点云的转换过程,掌握简单的点云融合方法。

    如果不出意外,最终点云融合结果如下:


    本文内容部分参考:PCL官网、半闲居士博客。

    师兄提醒:关注“计算机视觉life”微信公众号,菜单栏回复“点云”,就能下载代码框架和数据啦!
    原文链接:从零开始一起学习SLAM | 你好,点云
    相关推荐

    从零开始一起学习SLAM | 为什么要学SLAM?
    从零开始一起学习SLAM | 学习SLAM到底需要学什么?
    从零开始一起学习SLAM | SLAM有什么用?
    从零开始一起学习SLAM | C++新特性要不要学?
    从零开始一起学习SLAM | 为什么要用齐次坐标?
    从零开始一起学习SLAM | 三维空间刚体的旋转
    从零开始一起学习SLAM | 为啥需要李群与李代数?
    从零开始一起学习SLAM | 相机成像模型
    从零开始一起学习SLAM | 不推公式,如何真正理解对极约束?
    从零开始一起学习SLAM | 神奇的单应矩阵
    零基础小白,如何入门计算机视觉?

    1git clone https://github.com/PointCloudLibrary/pcl pcl-trunk

    欢迎关注公众号:计算机视觉life,一起探索计算机视觉新世界~
    ---------------------
    作者:electech6
    来源:CSDN
    原文:https://blog.csdn.net/electech6/article/details/84566319
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    Codeforces 1316B String Modification
    Codeforces 1305C Kuroni and Impossible Calculation
    Codeforces 1305B Kuroni and Simple Strings
    Codeforces 1321D Navigation System
    Codeforces 1321C Remove Adjacent
    Codeforces 1321B Journey Planning
    Operating systems Chapter 6
    Operating systems Chapter 5
    Abandoned country HDU
    Computer HDU
  • 原文地址:https://www.cnblogs.com/CV-life/p/10105480.html
Copyright © 2011-2022 走看看