PCL点云转深度图、求深度图边界并显示

目录

PCL点云转深度图、求深度图边界并显示代码

运行结果

理论说明和结果分析

PCL中点云转换

核心代码

核心函数 

PCL中边缘检测

核心代码

核心函数


PCL点云转深度图、求深度图边界并显示代码

详细说明看注释

#include <iostream>

#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/features/range_image_border_extractor.h>
#include <pcl/console/parse.h>
#include <pcl/common/file_io.h> // for getFilenameWithoutExtension

typedef pcl::PointXYZ PointType;

// --------------------
// -----Parameters-----
// --------------------
float angular_resolution = 0.5f;
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
bool setUnseenToMaxRange = false;

int
main(int argc, char** argv)
{
    angular_resolution = pcl::deg2rad(angular_resolution);

    // ------------------------------------------------------------------
    // -----Read pcd file or create example point cloud if not given-----
    // ------------------------------------------------------------------
    pcl::PointCloud<PointType>::Ptr point_cloud_ptr(new pcl::PointCloud<PointType>);
    pcl::PointCloud<PointType>& point_cloud = *point_cloud_ptr;
    pcl::PointCloud<pcl::PointWithViewpoint> far_ranges;
    Eigen::Affine3f scene_sensor_pose(Eigen::Affine3f::Identity());

    // Fill in the cloud data
    pcl::PCDReader reader;
    reader.read("rabbit.pcd", point_cloud);

    // -----------------------------------------------
    // -----Create RangeImage from the PointCloud-----
    // -----------------------------------------------
    float noise_level = 0.0;
    float min_range = 0.0f;
    int border_size = 1;
    pcl::RangeImage::Ptr range_image_ptr(new pcl::RangeImage);
    pcl::RangeImage& range_image = *range_image_ptr;
    range_image.createFromPointCloud(point_cloud, angular_resolution, pcl::deg2rad(360.0f), pcl::deg2rad(180.0f),
        scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
    range_image.integrateFarRanges(far_ranges);
    if (setUnseenToMaxRange)
        range_image.setUnseenToMaxRange();

    // --------------------------------------------
    // -----Open 3D viewer and add point cloud-----
    // --------------------------------------------
    pcl::visualization::PCLVisualizer viewer("3D Viewer");
    viewer.setBackgroundColor(1, 1, 1);
    viewer.addCoordinateSystem(1.0f, "global");
    pcl::visualization::PointCloudColorHandlerCustom<PointType> point_cloud_color_handler(point_cloud_ptr, 0, 0, 0);
    viewer.addPointCloud(point_cloud_ptr, point_cloud_color_handler, "original point cloud");

    // -------------------------
    // -----Extract borders-----
    // -------------------------
    pcl::RangeImageBorderExtractor border_extractor(&range_image);
    pcl::PointCloud<pcl::BorderDescription> border_descriptions;
    border_extractor.compute(border_descriptions);

    // ----------------------------------
    // -----Show points in 3D viewer-----
    // ----------------------------------
    pcl::PointCloud<pcl::PointWithRange>::Ptr border_points_ptr(new pcl::PointCloud<pcl::PointWithRange>),
        veil_points_ptr(new pcl::PointCloud<pcl::PointWithRange>),
        shadow_points_ptr(new pcl::PointCloud<pcl::PointWithRange>);
    pcl::PointCloud<pcl::PointWithRange>& border_points = *border_points_ptr,
        & veil_points = *veil_points_ptr,
        & shadow_points = *shadow_points_ptr;
    for (int y = 0; y < (int)range_image.height; ++y)
    {
        for (int x = 0; x < (int)range_image.width; ++x)
        {
            if (border_descriptions[y * range_image.width + x].traits[pcl::BORDER_TRAIT__OBSTACLE_BORDER])
                border_points.points.push_back(range_image[y * range_image.width + x]);
            if (border_descriptions[y * range_image.width + x].traits[pcl::BORDER_TRAIT__VEIL_POINT])
                veil_points.points.push_back(range_image[y * range_image.width + x]);
            if (border_descriptions[y * range_image.width + x].traits[pcl::BORDER_TRAIT__SHADOW_BORDER])
                shadow_points.points.push_back(range_image[y * range_image.width + x]);
        }
    }
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> border_points_color_handler(border_points_ptr, 0, 255, 0);//绿色,物体的边界
    viewer.addPointCloud<pcl::PointWithRange>(border_points_ptr, border_points_color_handler, "border points");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "border points");

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> veil_points_color_handler(veil_points_ptr, 255, 0, 0);//红色,物体与背景之间的过度点,雷达比较多
    viewer.addPointCloud<pcl::PointWithRange>(veil_points_ptr, veil_points_color_handler, "veil points");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "veil points");

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> shadow_points_color_handler(shadow_points_ptr, 0, 0, 255);//蓝色,是阴影的边界
    viewer.addPointCloud<pcl::PointWithRange>(shadow_points_ptr, shadow_points_color_handler, "shadow points");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "shadow points");

    //-------------------------------------
    // -----Show points on range image-----
    // ------------------------------------
    pcl::visualization::RangeImageVisualizer* range_image_borders_widget = NULL;
    range_image_borders_widget =
        pcl::visualization::RangeImageVisualizer::getRangeImageBordersWidget(range_image, -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), false,
            border_descriptions, "Range image with borders");
    // -------------------------------------


    //--------------------
    // -----Main loop-----
    //--------------------
    while (!viewer.wasStopped())
    {
        range_image_borders_widget->spinOnce();
        viewer.spinOnce();
    }
}

运行结果

深度图和边缘

点云显示的边缘

理论说明和结果分析

PCL中点云转换

核心代码

   float angular_resolution = 0.5f;
    pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;

    float noise_level = 0.0;
    float min_range = 0.0f;
    int border_size = 1;
    pcl::RangeImage::Ptr range_image_ptr(new pcl::RangeImage);
    pcl::RangeImage& range_image = *range_image_ptr;
    range_image.createFromPointCloud(point_cloud, angular_resolution, pcl::deg2rad(360.0f), pcl::deg2rad(180.0f),
        scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
    range_image.integrateFarRanges(far_ranges);
    if (setUnseenToMaxRange)
        range_image.setUnseenToMaxRange();

核心函数 

createFromPointCloud,按照函数参数的顺序依次设置:

point_cloud:输入点云

angular_resolution:角度分辨率,例如 角度分辨率应为0.5度,这意味着相邻像素表示的光束相差0.5度;

pcl::deg2rad(360.0f):maxAngleWidth 视角宽360度,其实180度即可满足一般要求还能降低计算复杂度;

pcl::deg2rad(180.0f):, maxAngleHeight 视角高360度,其实180度即可满足一般要求还能降低计算复杂度;

scene_sensor_pose:sensorPose将虚拟传感器的6自由度位置定义为原点,横摇=俯仰=偏航=0

coordinate_frame:CAMERA_FRAME x向右,y向下,z轴向前。LASER_FRAME,x朝前,y朝左,z朝上。

noise_level:对于noiseLevel=0,是用所有单个Z创建。0.05意味着,与最近点之间最大距离为5cm的所有点用于计算范围。(这个描述可能不是很准确,希望大家能集思广益)

min_range:大于零的话,会忽略一些距离比较近的点;

border_size:图像边缘的宽度,点云往外扩充的一段边缘;

PCL中边缘检测

核心代码

    pcl::RangeImageBorderExtractor border_extractor(&range_image);
    pcl::PointCloud<pcl::BorderDescription> border_descriptions;
    border_extractor.compute(border_descriptions);

核心函数

RangeImageBorderExtractor.comput(border_descriptions)

输出存在border_descriptions中,包括3类边缘,分别是:

1、物体的边缘;

2、阴影区域的边缘;

3、物体边缘和阴影边缘之间的点集;

可以显示在点云图像中,和深度图像中,可以看程序运行结果;

参考:

https://pcl.readthedocs.io/projects/tutorials/en/latest/range_image_creation.html#range-image-creation

https://pcl.readthedocs.io/projects/tutorials/en/latest/range_image_border_extraction.html#range-image-border-extraction

PCL是点云库(Point Cloud Library)的缩写,它提供了许多用于处理、分析和可视化点云数据的功能。将点云换为深度图可以通过PCL中的一些功能实现。 在PCL中,将点云换为深度图可以通过以下步骤实现: 1. 加载点云数据:首先,需要使用PCL中的PointCloud类来加载点云数据。点云数据可以来自多种来源,如激光雷达、深度相机等。可以使用PCL提供的方法读取和解析点云数据。 2. 点云降采样:如果点云数据较大,可以先对点云进行降采样,以减少计算量和内存使用。PCL提供了多种点云降采样的方法,如体素网格滤波、统计滤波等。这些方法可以对点云进行过滤,只保留一部分点云,这样可以简化后续的处理步骤。 3. 点云换为深度图:一旦点云数据准备好,可以使用PCL提供的Projection类来将点云换为深度图。Projection类提供了将点云数据投影到给定分辨率的深度图像中的方法。通过将点云数据映射到深度图像中,可以获得每个像素位置对应的深度值。 4. 可视化或保存深度图:最后,我们可以选择将深度图可视化或保存为图像文件。PCL提供了可视化和图像保存的方法,可以将深度图显示在屏幕上或保存为文件。 总结起来,通过PCL库提供的功能,可以方便地将点云数据换为深度图。这为进一步的点云分析和处理提供了更多的可能性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值