PCL点云库常用小技巧

1.保存点云数据

//普通格式ASSIC(占用内存较大)
pcl::PCDWriter writer;
writer.write(s_pcd,laserCloudIn);

//bin格式(占用内存较小)
pcl::io::savePCDFileBinary(s_pcd, *cloud);

2.查找点云在X、Y、Z轴的极值

pcl::PointXYZ minPt, maxPt;
pcl::getMinMax3D (*cloud, minPt, maxPt);

3.如果知道了要保存点的索引,如何从原点云中拷贝点到新点云?

pcl::PointCloud::Ptr cloudOut(new pcl::PointCloud);
std::vector indexs = { 1, 2, 5 };
pcl::copyPointCloud(*cloud, indexs, *cloudOut);

4.如何从点云里删除和添加点?

pcl::PointCloud::iterator index = cloud->begin();
cloud->erase(index);//删除第一个
index = cloud->begin() + 5;
cloud->erase(index);//删除第5个
pcl::PointXYZ point = { 1, 1, 1 };
//在索引号为5的位置上插入一点,之后的所有点后移一位
cloud->insert(cloud->begin() + 5, point);
cloud->push_back(point);//从点云最后面插入一点

5.如何对点云进行全局或局部变换

//全部
pcl::transformPointCloud(*cloud,*transform_cloud1,transform_1);
        
//局部
//第一个参数为输入,第二个参数为输入点云中部分点集索引,第三个为存储对象,第四个是变换矩阵。
pcl::transformPointCloud(*cloud,pcl::PointIndices indices,*transform_cloud1,matrix); 

6.链接两个点云字段(两点云大小必须相同)

pcl::PointCloud::Ptr cloud_with_nomal (new pcl::PointCloud);
pcl::concatenateFields(*cloud,*cloud_normals,*cloud_with_nomal);

7.如何从点云中删除无效点

vector indices;
pcl::removeNaNFromPointCloud(*cloud,*output,indices);

8.计算质心

Eigen::Vector4f centroid;//质心
pcl::compute3DCentroid(*cloud_smoothed,centroid); //估计质心的坐标

9.计算点云的法向量

pcl::NormalEstimation ne;
pcl::PointCloud::Ptr pcNormal(new pcl::PointCloud);  
pcl::search::KdTree::Ptr tree(new pcl::search::KdTree);
tree->setInputCloud(inCloud);  
ne.setInputCloud(inCloud);  
ne.setSearchMethod(tree);  
ne.setKSearch(50);  
//ne->setRadiusSearch (0.03);   
ne.compute(*pcNormal);

10.提取点云的边界

pcl::PointCloud boundaries; //保存边界估计结果pcl::BoundaryEstimation boundEst; //定义一个进行边界特征估计的对象
pcl::NormalEstimation normEst; //定义一个法线估计的对象
pcl::PointCloud::Ptr normals(new pcl::PointCloud); //保存法线估计的结果
pcl::PointCloud::Ptr cloud_boundary (new pcl::PointCloud); 
normEst.setInputCloud(pcl::PointCloud::Ptr(cloud)); 
normEst.setRadiusSearch(reforn); //设置法线估计的半径
normEst.compute(*normals); //将法线估计结果保存至normals

 
boundEst.setInputCloud(cloud); //设置输入的点云
boundEst.setInputNormals(normals); //设置边界估计的法线,因为边界估计依赖于法线
boundEst.setRadiusSearch(re); //设置边界估计所需要的半径
boundEst.setAngleThreshold(M_PI/4); //边界估计时的角度阈值
boundEst.setSearchMethod(pcl::search::KdTree::Ptr (new pcl::search::KdTree)); //设置搜索方式KdTree
boundEst.compute(boundaries); //将边界估计结果保存在boundaries

11.k近邻和半径搜索

pcl::KdTreeFLANNkdtree; //创建kdtree搜索对象
kdtree.setInputCloud(cloud);           //载入点云
pcl::PointXYZ searchPoint;              //设置查询点并赋随机值
//K近邻搜索
int K = 10;                             //搜索最近邻的点数
vectorpointIdxNKNSearch(K);        //存放最近邻点的索引
vectorpointNKNSquaredDistance(K);//对应的距离平方
kdtree.nearestKSearch(searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance)
//半径内搜索
std::vector pointIdxRadiusSearch;
std::vector pointRadiusSquaredDistance;
float radius; //定义搜索半径
kdtree.radiusSearch(searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance);

12.添加新的点云类

//有自定义点云类型时要加入该头文件才能使用PCL库模板函数
#include   
//运用相应的函数需加入以下相应头文件
//如:直通滤波器
#include 

//定义一个新的点云类
struct PointXYZIR
{
  PCL_ADD_POINT4D
  float intensity;
  uint16_t ring;                   ///< laser ring number
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW  //确保new操作符对齐
} EIGEN_ALIGN16; //强制SSE对齐

POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZIR, (float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(uint16_t, ring, ring))

 

你可能感兴趣的:(使用技巧)