IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    三维点云处理入门(10):点云和其他类型数据(深度图像)的转换

    52txr发表于 2024-03-19 17:03:00
    love 0

    深度图像是一种记录了相机到场景中各点距离的特殊类型图像,每个像素值代表该点的距离,近处像素值低,远处高。这种图像更多地表现出物体的形状和大小而非颜色或光线。深度图像可以转换为点云数据,反之亦然。点云转深度图像主要依赖pcl_range_image类,通过设置相关参数,如角分辨率、最大视角、传感器位置和方向等,可以从点云创建出深度图像。

    深度图像

    深度图像,有时也称为距离影像,是一种特殊类型的图像,它不像普通的照片那样记录颜色,而是记录了相机到场景中各个点的距离。这种距离就是“深度”。想象一下,你在看一个物体,深度图像会告诉你每个部分距离你有多远。

    这样的图像看起来可能和普通照片不太一样,因为它们更多地表现出物体的形状和大小,而不是颜色或光线。每个像素的值代表到那个点的距离,距离近的地方像素值低,距离远的地方像素值高。

    深度图像

    深度图像可以被转换为点云数据,这是一种由很多小点组成的数据形式,每个点都有自己的位置(x, y, z坐标),代表空间中的一个点。反过来,如果你有一个包含足够信息的点云,你也可以从中创建出深度图像。

    深度图像 = 普通RGB三通道彩色图像 + Depth Map

    (Depth map, 2.5D image, RGB-D)

    深度图像转换

    点云转深度图像

    PCL的深度图像主要依赖pcl_range_image类:

    #include <pcl/point_cloud.h>
    #include <pcl/range_image/range_image.h>
    
    // 假设你已经有了一个PointCloud类型的点云变量cloud
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    
    // ... 点云的加载或处理 ...
    
    // 定义相机的参数
    float angularResolution = (float)(1.0f * (M_PI/180.0f));  // 角分辨率,以弧度为单位
    float maxAngleWidth = (float)(360.0f * (M_PI/180.0f));    // 水平最大角度
    float maxAngleHeight = (float)(180.0f * (M_PI/180.0f));   // 垂直最大角度
    
    Eigen::Affine3f sensorPose = Eigen::Affine3f(Eigen::Translation3f(cloud->sensor_origin_[0],
                                                                      cloud->sensor_origin_[1],
                                                                      cloud->sensor_origin_[2])) * 
                                 Eigen::Affine3f(cloud->sensor_orientation_);
    float noiseLevel = 0.00;
    float minRange = 0.0f;
    int borderSize = 1;
    
    //坐标系类型,通常是相机坐标系。
    pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
    
    
    //使用了Boost库中的shared_ptr智能指针来管理pcl::RangeImage对象的内存
    //boost::shared_ptr是一个智能指针,用来自动管理对象的生命周期。当指向的对象不再使用时,它会自动释放内存。这避免了手动管理内存的问题。
    boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage);
    
    //创建了一个pcl::RangeImage类型的引用rangeImage,指向range_image_ptr所管理的对象。通过这种方式,你可以使用rangeImage来访问和操作range_image_ptr指向的对象,就像使用普通对象一样。
    pcl::RangeImage &rangeImage = *range_image_ptr;
    
    //从点云创建范围图像
    rangeImage.createFromPointCloud(cloud, angularResolution, maxAngleWidth, maxAngleHeight, sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
    
    /*
    cloud:源点云数据。
    angularResolution:图像的角分辨率。
    maxAngleWidth:图像的最大水平视角。
    maxAngleHeight:图像的最大垂直视角。
    sensorPose:定义了传感器(或相机)在世界坐标系中的位置和方向。
    coordinate_frame:坐标系类型,通常是相机坐标系。
    noiseLevel:噪声水平,用于图像处理。
    minRange:传感器可以检测的最小距离。
    borderSize:图像边框的大小。
    */

    其他的一些从点云创建范围图像函数:

    • createFromPointCloudWithFixedSize()
    • createFromPointCloudWithKnownSize()
    • createFromPointCloudWithViewpoints()


沪ICP备19023445号-2号
友情链接