PCL学习
从PCD文件中读取点云数据
loadPCDFile书中案例
代码
#include <iostream> //标准C++库中的输入输出的头文件
#include <pcl/io/pcd_io.h> //PCD读写类相关的头文件
#include <pcl/point_types.h> //PCL中支持的点类型的头文件
int
main(int argc, char** argv)
{
//创建一个PointCloud<pcl::PointXYZ> boost共享指针并进行实例化
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
//从磁盘上加载PointCloud数据到二进制存储块中,打开点云文件
if (pcl::io::loadPCDFile<pcl::PointXYZ>("test_pcd.pcd", *cloud) == -1)
{
PCL_ERROR("Couldn't read file test_pcd.pcd \n");
return (-1);
}
//默认二进制块读取转换为模块化的PointCLoud格式里pcl::PointXYZ作为点类型
std::cout << "Loaded "
<< cloud->width * cloud->height
<< " data points from test_pcd.pcd with the following fields: "
<< std::endl;
for (size_t i = 0; i < cloud->points.size(); ++i)
std::cout << " " << cloud->points[i].x
<< " " << cloud->points[i].y
<< " " << cloud->points[i].z << std::endl;//在标准输出上打印数据。
getchar();
return (0);
}
loadPCDFile例二
pcl::PointCloud<pcl::PointXYZ> cloud;
if (pcl::io::loadPCDFile<pcl::PointXYZ>("车载道路2.pcd", cloud) == -1)
{
PCL_ERROR("Cloudn't read file!");
return -1;
}
std::cout << "读取点个数: " << cloud.points.size() << std::endl;
pcl::PCDReader例子
pcl::PCDReader reader;
//创建一个`PointCloud<PointXYZ>` boost共享指针并进行实例化
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
//读取pcd文件,用指针传递给cloud
reader.read ("xcmg-test1.pcd", *cloud);
std::cout << "PointCloud before filtering has: " << cloud->points.size () << " data points." << std::endl; //*
loadPCDFile()与savePCDFile函数内部其实是调用的reader.read()和writer.write函数,不同写法本质上一样
向PCD文件写入点云数据
savePCDFileASCII书中案例
代码
#include <iostream> //标准C++库中的输入输出的头文件
#include <pcl/io/pcd_io.h> //PCD读写类相关的头文件
#include <pcl/point_types.h> //PCL中支持的点类型的头文件
int
main(int argc, char** argv)
{
//实例化的模板类PointCloud,每一个点的类型都设置为pcl::PointXYZ
/*************************************************
点PointXYZ类型对应的数据结构
Structure PointXYZ{
float x;
float y;
float z;
};
**************************************************/
pcl::PointCloud<pcl::PointXYZ> cloud;
// 创建点云 并设置适当的参数(width/height/is_dense)
cloud.width = 5;
cloud.height = 1;
cloud.is_dense = false; //不是稠密型的
cloud.points.resize(cloud.width * cloud.height); //点云总数大小
//用随机数的值填充PointCloud点云对象
for (size_t i = 0; i < cloud.points.size(); ++i)
{
cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
//把PointCloud对象数据存储在 test_pcd.pcd文件中
pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);
//打印输出存储的点云数据
std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;
for (size_t i = 0; i < cloud.points.size(); ++i)
std::cerr << " " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;
getchar();
return (0);
}
附加
pcl::io::savePCDFile<pcl::PointXYZ>("车载道路2_.pcd", cloud); //默认二进制方式保存
pcl::io::savePCDFileASCII<pcl::PointXYZ>("车载道路2_ASCII.pcd", cloud); //ASCII方式保存
pcl::io::savePCDFileBinary<pcl::PointXYZ>("车载道路2_Binary.pcd", cloud); //二进制方式保存
pcl::PCDWriter例子
pcl::PCDWriter writer;
writer.write<pcl::PointXYZI>("name_cluster.pcd", *INcloud, false);//将点云保存到PCD文件中
//*INcloud该参数带不带*号,取决于你自己定义的cloud类型,如上使用的是Ptr,智能指针所以下边传参也要带*号
附加
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ>("1车载道路2_.pcd", cloud); //默认二进制方式保存
writer.writeASCII<pcl::PointXYZ>("1车载道路2_ASCII.pcd", cloud); //ASCII方式保存
writer.writeBinary<pcl::PointXYZ>("1车载道路2_Binary.pcd", cloud); //二进制方式保存
PCD文件可视化
PCLVisualizer书中案例
PCLVisualizer可视化类是PCL中功能最全的可视化类,如显示法线、点云着色、绘制多种形状和开辟多个视口。
可视化单个点云
#include <iostream>
#include <boost/thread/thread.hpp>
#include <pcl/common/common_headers.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
simpleVis函数实现最基本的点云可视化操作,
boost::shared_ptr<pcl::visualization::PCLVisualizer> simpleVis (pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{
//创建视窗对象并给标题栏设置一个名称“3D Viewer”并将它设置为boost::shared_ptr智能共享指针,这样可以保证指针在程序中全局使用,而不引起内存错误
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
//设置视窗的背景色,可以任意设置RGB的颜色,这里是设置为黑色
viewer->setBackgroundColor (0, 0, 0);
/*将点云添加到视窗对象中,并定一个唯一的字符串作为ID 号,利用此字符串保证在其他成员中也能标志引用该点云,多次调用addPointCloud可以实现多个点云的添加,每调用一次就会创建一个新的ID号,如果想更新一个已经显示的点云,先调用removePointCloud(),并提供需要更新的点云ID 号,也可使用updatePointCloud*/
viewer->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud");
//用于改变显示点云的尺寸,可以利用该方法控制点云在视窗中的显示方法,1设置显示点云大小
viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
//通过设置照相机参数使得从默认的角度和方向观察点云
viewer->initCameraParameters ();
return (viewer);
}
多视角显示
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewportsVis (pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud, pcl::PointCloud<pcl::Normal>::ConstPtr normals1, pcl::PointCloud<pcl::Normal>::ConstPtr normals2)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
viewer->initCameraParameters ();
//以上是创建视图的标准代码
int v1(0); //创建新的视口
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //4个参数分别是X轴的最小值,最大值,Y轴的最小值,最大值,取值0-1,v1是标识
viewer->setBackgroundColor (0, 0, 0, v1);//设置视口的背景颜色
viewer->addText("Radius: 0.01", 10, 10, "v1 text", v1); //添加一个标签区别其他窗口 利用RGB颜色着色器并添加点云到视口中
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);//颜色处理对象
viewer->addPointCloud<pcl::PointXYZRGB> (cloud, rgb, "sample cloud1", v1);
//对第二视口做同样的操作,使得做创建的点云分布于右半窗口,将该视口背景赋值于灰色,以便明显区别,虽然添加同样的点云,给点云自定义颜色着色
int v2(0);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor (0.3, 0.3, 0.3, v2);
viewer->addText("Radius: 0.1", 10, 10, "v2 text", v2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> single_color(cloud, 0, 255, 0);
viewer->addPointCloud<pcl::PointXYZRGB> (cloud, single_color, "sample cloud2", v2);
//为所有视口设置属性,
viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud1");
viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud2");
viewer->addCoordinateSystem (1.0);//添加法线 每个视图都有一组对应的法线
viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals1, 10, 0.05, "normals1", v1);
viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals2, 10, 0.05, "normals2", v2);
return (viewer);
}
常用显示方法
boost::shared_ptr<pcl::visualization::PCLVisualizer>
simpleVis (pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{
// --------------------------------------------
// -----Open 3D viewer and add point cloud-----
// --------------------------------------------
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
viewer->setBackgroundColor (0, 0, 0);
viewer->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud");
viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
//viewer->addCoordinateSystem (1.0);
viewer->initCameraParameters ();
return (viewer);
int main()
{
...
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
viewer = simpleVis(final);
while (!viewer->wasStopped ())
{
viewer->spinOnce (100);
boost::this_thread::sleep (boost::posix_time::microseconds (100000));
}
return 0;
}