PCL PointIndices类型介绍
引用参考:https://blog.youkuaiyun.com/weixin_45867382/article/details/121711904
PointIndices 类在 PCL 中非常常用,它用于保存点云的索引,在查找、提取、删除等操作中都是将要操作的点云索引放到 PointIndices 中,然后再使用一些 copy 函数,利用保存的该索引将源点云保存至新的点云中。
PointIndices.h
Point Cloud Library 1.12.1版本定义
1 #pragma once
2
3 #include <ostream>
4
5 // Include the correct Header path here
6 #include <pcl/PCLHeader.h>
7 #include <pcl/types.h>
8
9 namespace pcl
10 {
11 struct PointIndices
12 {
13 using Ptr = shared_ptr< ::pcl::PointIndices>;
14 using ConstPtr = shared_ptr<const ::pcl::PointIndices>;
15
16 PointIndices ()
17 {}
18
19 ::pcl::PCLHeader header;
20
21 Indices indices;
22 }; // struct PointIndices
23
24 using PointIndicesPtr = PointIndices::Ptr;
25 using PointIndicesConstPtr = PointIndices::ConstPtr;
26
27 inline std::ostream& operator << (std::ostream& s, const ::pcl::PointIndices &v)
28 {
29 s << "header: " << std::endl;
30 s << " " << v.header;
31 s << "indices[]" << std::endl;
32 for (std::size_t i = 0; i < v.indices.size (); ++i)
33 {
34 s << " indices[" << i << "]: ";
35 s << " " << v.indices[i] << std::endl;
36 }
37 return (s);
38 }
39 } // namespace pcl
从源码中可以看到,PointIndices 其实是一个结构体,里面包含了 PCLHeader 类型的成员变量 header,用于保存基本信息,核心是成员变量 indices,它为 std::vector 类型,用于存放点云的索引,另外还有指向该结构体的两个指针。最后还重载了输出 (<<) 操作符。
一般在使用 PointIndices 时,需要创建该结构体的指针,使用如下代码创建:
// 创建方式1:利用 vector<int>
std::vector<int> vec_indexs;
pcl::IndicesPtr pIndexs_new(new std::vector<int>(vec_indexs));
pcl::IndicesPtr pIndexs_boost = boost::make_shared<std::vector<int>>(vec_indexs);
// pcl::IndicesPtr pIndexs_boost = std::make_shared<std::vector<int>>(vec_indexs); // 1.11.1 版本,命名空间改变
// 创建方式2:利用 PointIndices
pcl::PointIndices pointIndices;
pcl::IndicesPtr pPointIndexs_new(new std::vector<int>(pointIndices.indices));
pcl::IndicesPtr pPointIndexs_boost = boost::make_shared<std::vector<int>>(pointIndices.indices);
// pcl::IndicesPtr pPointIndexs_boost = std::make_shared<std::vector<int>>(pointIndices.indices); // 1.11.1 版本,命名空间改变
关键是索引点如何提出是一个关键性问题,我看博主用的copyPointCloud 函数,尝试了几次,没有成功,可能也是由于版本不一致?后续再尝试,会及时补上经验。
下面是未尝试成功的copyPointCloud 函数
copyPointCloud 函数将输入点云中的点(inputCloud),按照索引(pointIndices.indices)载入到输出点云中(outputCloud)。
// ...
// 创建输入输出点云
pcl::PointCloud<pcl::PointXYZ>::Ptr inputCloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr outputCloud(new pcl::PointCloud<pcl::PointXYZ>);
// 创建索引
pcl::PointIndices pointIndices;
// 处理输入点云至索引
// ...
// 提取点云
pcl::copyPointCloud(*inputCloud, pointIndices.indices, *outputCloud);
我在欧式聚类的提取过程中遇到:
//欧式聚类关键部分代码
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud(cloud_filtered);//创建点云索引向量,用于存储实际的点云信息
std::vector<pcl::PointIndices> cluster_indices;
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
ec.setClusterTolerance(0.1); //设置近邻搜索的搜索半径为2cm
ec.setMinClusterSize(500);//设置一个聚类需要的最少点数目为100
ec.setMaxClusterSize(1000000); //设置一个聚类需要的最大点数目为25000
ec.setSearchMethod(tree);//设置点云的搜索机制
ec.setInputCloud(cloud_filtered);
ec.extract(cluster_indices);//从点云中提取聚类,并将点云索引保存在cluster_indices中
std::cout << "cluster_indices size is " << cluster_indices.size() << std::endl;
std::vectorpcl::PointIndices cluster_indices;其中定义了一个容器存储PointIndices这种类型的索引点
最后输出采用:
int j = 0;
for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin(); it != cluster_indices.end(); ++it)
{
pcl::PointCloud<PoinT>::Ptr cloud_cluster(new pcl::PointCloud<PoinT>);
for (const auto& idx : it->indices)
{
cloud_cluster->push_back((*cloud_filtered)[idx]); //*
}
将索引点压入cloud_cluster中
std::cout << "fullCloud->points size is " << cloud_filtered->points.size() << std::endl;
std::string str = "C:\\Users\\Administrator\\Desktop\\JULEI" + std::to_string(j) + ".pcd";
pcl::io::savePCDFileASCII(str, *cloud_cluster);
最后输出cloud_cluster.pcd 的二进制文件。