问题描述:
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)