Bootstrap

调用 PCLVisualizer::addPointCloud 函数时,传递的参数类型与该函数的预期参数类型不匹配。

问题描述:

error: no matching function for call to ‘pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange>::PointCloudColorHandlerCustom(boost::shared_ptr<pcl::RangeImage>&, int, int, int)’
 stom<pcl::PointWithRange> range_image_color_handler(range_image_ptr, 0, 0, 0);

no matching function for call to ‘pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange>::PointCloudColorHandlerCustom(boost::shared_ptr<pcl::RangeImage>&, int, int, int)’
 stom<pcl::PointWithRange> range_image_color_handler(range_image_ptr, 0, 0, 0);
源代码入下:

#include<pcl/range_image/range_image.h>     //关于深度图像的头文件
#include<pcl/io/pcd_io.h>
#include<pcl/visualization/pcl_visualizer.h>            //pcl可视化头文件
#include<pcl/visualization/range_image_visualizer.h>    //深度图可视化头文件

using namespace std;

int main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ> &pointCloud = *pointCloudPtr;

    pcl::io::loadPCDFile("bunny.pcd", pointCloud);

    //实现一个呈矩形的点云
    //angular_resolution为模拟的深度传感器的角度分辨率,即深度图像中一个像素对应的角度大小
    float angularResolution = (float)(1.0f * (M_PI / 180.0f));  //弧度1度

    //max_angle_width为模拟的深度传感器的水平最大采样角度
    float maxAngleWidth = (float)(360.0f * (M_PI / 180.0f));    //弧度360度
    //max_angle_height为模拟的深度传感器的垂直方向最大采样角度   都转为弧度
    float maxAngleHeight = (float)(180.0f * (M_PI / 180.0f));
    
    //传感器的采集位置
    Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);

    //深度图像遵循坐标系统
    pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
    float noiseLevel = 0.00;    //noise_level获取深度图像深度时,近邻点对查询点距离值的影响水平
    float minRange = 0.0f;      //最小获取深度,小于最小获取深度的位置为传感器盲区
    float borderSize = 1;       //深度图像的边缘宽度

    boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage);   
    pcl::RangeImage &rangeImage = *range_image_ptr;

    //从点云中创建深度图像
    rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight, sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
    
    /*
    关于range_image.createFromPointCloud()参数的解释,涉及的角度都以弧度为单位
    point_cloud为创建深度图像所需的点云
    angular_resolution_x深度传感器X方向的角度分辨率
    angular_resolution_y深度传感器Y方向的角度分辨率
    pcl::deg2rad(360.0f)深度传感器的水平最大采样角度
    pcl::deg2rad(180.0f)深度传感器的垂直最大采样角度
    scene_sensor_pose传感器位姿放射变换矩阵,默认为4*4的单位变换矩阵
    coordinate_frame,定义按照那种坐标系统的习惯,默认为CAMERA_FRAME
    noise_level获取深度图像深度时,邻近点对查询点距离值的影响水平
    min_range   最小获取距离,小于这个距离的位置为传感器盲区
    border_size 获取深度图像边缘的宽度,默认为0
    */
   cout << rangeImage << endl;

   //创建3D窗口并添加点云
   pcl::visualization::PCLVisualizer viewer("3D Viewer");
   viewer.setBackgroundColor(1, 1, 1);


    //添加深度图点云
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler(range_image_ptr, 0, 0, 0);
    viewer.addPointCloud(range_image_ptr, range_image_color_handler, "range image");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "range image");
    //添加原始代点云
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> org_image_color_handler(pointCloudPtr, 255, 100, 0);
    viewer.addPointCloud(pointCloudPtr, org_image_color_handler, "original image");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original image");

    viewer.initCameraParameters();
    viewer.addCoordinateSystem(1.0);

     while (!viewer.wasStopped())
    {
        viewer.spinOnce();
        pcl_sleep(0.01);
    }
    return (0);


}




问题分析

遇到的问题: 我们在添加深度图点云时,pcl::RangeImage 类型不能直接用于 PCLVisualizer::addPointCloud 函数。这个函数通常用于处理 pcl::PointCloud<T> 类型的数据,而 pcl::RangeImage 并不是一个标准的 PointCloud 类型。

要解决这个问题,你需要将 pcl::RangeImage 转换为 pcl::PointCloud<pcl::PointWithRange> 类型,然后才能使用 addPointCloud 函数,如下面代码所示。

 // 将RangeImage转换为PointCloud<PointWithRange>
    pcl::PointCloud<pcl::PointWithRange>::Ptr pointCloudWithRangePtr(new pcl::PointCloud<pcl::PointWithRange>());
    for (int y = 0; y < rangeImage.height; ++y)
    {
        for (int x = 0; x < rangeImage.width; ++x)
        {
            if (rangeImage.isInImage(x, y))
            {
                pcl::PointWithRange point;
                point.x = rangeImage.getPoint(x, y).x;
                point.y = rangeImage.getPoint(x, y).y;
                point.z = rangeImage.getPoint(x, y).z;
                point.range = rangeImage.getPoint(x, y).range;
                pointCloudWithRangePtr->points.push_back(point);
            }
        }
    }
    pointCloudWithRangePtr->width = static_cast<uint32_t>(pointCloudWithRangePtr->points.size());
    pointCloudWithRangePtr->height = 1;


解决方案:

在添加点云之前,将 pcl::RangeImage 转换为 pcl::PointCloud<pcl::PointWithRange> 类型即可,修改完代码如下:

#include <pcl/range_image/range_image.h>     //关于深度图像的头文件
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>            //pcl可视化头文件
#include <pcl/visualization/range_image_visualizer.h>    //深度图可视化头文件

using namespace std;

int main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ> &pointCloud = *pointCloudPtr;

    pcl::io::loadPCDFile("bunny.pcd", pointCloud);

    // 实现一个呈矩形的点云
    // angular_resolution为模拟的深度传感器的角度分辨率,即深度图像中一个像素对应的角度大小
    float angularResolution = (float)(1.0f * (M_PI / 180.0f));  // 弧度1度

    // max_angle_width为模拟的深度传感器的水平最大采样角度
    float maxAngleWidth = (float)(360.0f * (M_PI / 180.0f));    // 弧度360度
    // max_angle_height为模拟的深度传感器的垂直方向最大采样角度,都转为弧度
    float maxAngleHeight = (float)(180.0f * (M_PI / 180.0f));
    
    // 传感器的采集位置
    Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);

    // 深度图像遵循坐标系统
    pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
    float noiseLevel = 0.00;    // noise_level获取深度图像深度时,近邻点对查询点距离值的影响水平
    float minRange = 0.0f;      // 最小获取深度,小于最小获取深度的位置为传感器盲区
    float borderSize = 1;       // 深度图像的边缘宽度

    pcl::RangeImage rangeImage;
    rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight, sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
    
    /*
    关于range_image.createFromPointCloud()参数的解释,涉及的角度都以弧度为单位
    point_cloud为创建深度图像所需的点云
    angular_resolution_x深度传感器X方向的角度分辨率
    angular_resolution_y深度传感器Y方向的角度分辨率
    pcl::deg2rad(360.0f)深度传感器的水平最大采样角度
    pcl::deg2rad(180.0f)深度传感器的垂直最大采样角度
    scene_sensor_pose传感器位姿放射变换矩阵,默认为4*4的单位变换矩阵
    coordinate_frame,定义按照那种坐标系统的习惯,默认为CAMERA_FRAME
    noise_level获取深度图像深度时,邻近点对查询点距离值的影响水平
    min_range   最小获取距离,小于这个距离的位置为传感器盲区
    border_size 获取深度图像边缘的宽度,默认为0
    */
    cout << rangeImage << endl;

    // 将RangeImage转换为PointCloud<PointWithRange>
    pcl::PointCloud<pcl::PointWithRange>::Ptr pointCloudWithRangePtr(new pcl::PointCloud<pcl::PointWithRange>());
    for (int y = 0; y < rangeImage.height; ++y)
    {
        for (int x = 0; x < rangeImage.width; ++x)
        {
            if (rangeImage.isInImage(x, y))
            {
                pcl::PointWithRange point;
                point.x = rangeImage.getPoint(x, y).x;
                point.y = rangeImage.getPoint(x, y).y;
                point.z = rangeImage.getPoint(x, y).z;
                point.range = rangeImage.getPoint(x, y).range;
                pointCloudWithRangePtr->points.push_back(point);
            }
        }
    }
    pointCloudWithRangePtr->width = static_cast<uint32_t>(pointCloudWithRangePtr->points.size());
    pointCloudWithRangePtr->height = 1;

    // 创建3D窗口并添加点云
    pcl::visualization::PCLVisualizer viewer("3D Viewer");
    viewer.setBackgroundColor(1, 1, 1);

    // 添加深度图点云
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler(pointCloudWithRangePtr, 0, 0, 0);
    viewer.addPointCloud(pointCloudWithRangePtr, range_image_color_handler, "range image");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "range image");

    // 添加原始点云
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> org_image_color_handler(pointCloudPtr, 255, 100, 0);
    viewer.addPointCloud(pointCloudPtr, org_image_color_handler, "original image");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original image");

    viewer.initCameraParameters();
    viewer.addCoordinateSystem(1.0);

    while (!viewer.wasStopped())
    {
        viewer.spinOnce();
        pcl_sleep(0.01);
    }

    return 0;
}


 CMakeLists.txt如下:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(cloud_viewer)

find_package(PCL 1.2 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (range_image_creation range_image_creation.cpp)
target_link_libraries (range_image_creation ${PCL_LIBRARIES})

显示效果:

(能看得出来是一只小兔子嘛hhhhhh)

;