2、RGB-D 从图像到点云 detectFeatures

(在做高博的“一起做RGB-D_SLAM”的一些问题,作为自己笔记总结,以督促自己完成并理解)
一起做--从图像到点云
接着上面的在qt下新建slam项目来的。
1、在src/CMakeLists.txt下添加:

#############################generatePointCloud
# 增加PCL库的依赖
FIND_PACKAGE( PCL REQUIRED COMPONENTS common io )

# 增加opencv的依赖
FIND_PACKAGE( OpenCV REQUIRED )

# 添加头文件和库文件
ADD_DEFINITIONS( ${PCL_DEFINITIONS} )
INCLUDE_DIRECTORIES( ${PCL_INCLUDE_DIRS}  )
LINK_LIBRARIES( ${PCL_LIBRARY_DIRS} )

ADD_EXECUTABLE( generate_pointcloud gpointcloud.cpp )
TARGET_LINK_LIBRARIES( generate_pointcloud ${OpenCV_LIBS}
    ${PCL_LIBRARIES} )

在qt里面,右上角,选File -> new file or project -> c++ ->c++ source file 输入name:” generatePointCloud.cpp “  代码与高博的一起做一样,照着打的

#include 
#include 

using namespace std;

#include 
#include 

#include 
#include 

// 定义点云类型
typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud PointCLoud;


// 相机内参
const double camera_factor = 1000;                        //通常1000的值代表1米,深度图里每个像素点的读数除以1000,就是它离你的真实距离了
const double camera_cx = 325.5;
const double camera_cy = 253.5;
const double camera_fx = 518.0;
const double camera_fy = 519.0;

int main (int argc, char** argv)
{
    cv::Mat rgb, depth;                         //读取./data/rgb.png和./data/depth.png,并转化为点云
    rgb = cv::imread( "./data/rgb.png" );
    depth = cv::imread("./data/depth.png",-1);        //注意flags设置-1,表示读取原始数据不做任何修改

    PointCLoud::Ptr cloud (new PointCLoud);      // 使用智能指针,创建一个空点云。这种指针用完会自动释放。
    for (int m = 0 ;m //我们按照“先列后行”的顺序,遍历了整张深度图
        for (int n = 0;n (m)[n];                //深度图第m行,第n行的数据可以使用depth.ptr(m) [n]来获取
            //其中,cv::Mat的ptr函数会返回指向该图像第m行数据的头指针。然后加上位移n后,这个指针指向的数据就是我们需要读取的数据
            if (d == 0)                                        // d 可能没有值,若如此,跳过此点
                continue;
            PointT p;                                         // d 存在值,则向点云增加一个点

            p.z = double(d) / camera_factor;  ////先求出空间点
            p.x = (n - camera_cx) * p.z / camera_fx;
            p.y = (m - camera_cy) * p.z / camera_fy;


            // 从rgb图像中获取它的颜色
            // rgb是三通道的BGR格式图,所以按下面的顺序获取颜色
            p.b = rgb.ptr(m)[n*3];               //通过depth.ptr能读出i行j列的深度值
            if(d==0)                                     //如果是hole,则直接跳过
                continue;
            p.g = rgb.ptr(m)[n*3+1];
            p.r = rgb.ptr(m)[n*3+2];

            cloud->points.push_back( p );                  //将p储存到cloud中

        }
    cloud->height = 1;                                     //设点云数据
    cloud->width = cloud->points.size();
    cout<<"point cloud size = "<points.size()<is_dense = false;
    pcl::io::savePCDFile("./pointclod.pcd", *cloud); //把整个点云存储为 ./data/pointcloud.pcd 文件
  // 清除数据并退出
    cloud->points.clear();
    cout<<"Point cloud saved."<return 0;
}

将data里的两张图片放到slam项目目录下,然后编译
但注意不能在qt里直接运行,会出现这个错误:
这里写图片描述
打开终端输入,在slam项目目录下

$ bin/generate_pointcloud

即可在data目录下生成点云文件。现在,你肯定希望查看一下新生成的点云了。如果已经安装了pcl,就可以通过:

$ pcl_viewer pointcloud.pcd

来查看新生成的点云:
2、RGB-D 从图像到点云 detectFeatures_第1张图片

你可能感兴趣的:(slam初级)