最近开始动手做实验,之前写了一个小实验利用到了PCL库中的索引;
现在在写利用PCL中的RegionGrowing类来分割生成面片,无论是迭代生成还是进行提取都需要用到pcl库中定义的索引,
虽然搞的不是太明白,还是想写下来来记录自己的思路。
先看一下PCL是如何定义PointIndices的结构:
1 struct PointIndices
2 {
3 PointIndices () : header (), indices ()
4 {}
5
6 ::pcl::PCLHeader header;
7
8 std::vector<int> indices;
9
10 public:
11 typedef boost::shared_ptr< ::pcl::PointIndices> Ptr;
12 typedef boost::shared_ptr< ::pcl::PointIndices const> ConstPtr;
13 }; // struct PointIndices
1 typedef boost::shared_ptr< ::pcl::PointIndices> PointIndicesPtr;
2 typedef boost::shared_ptr< ::pcl::PointIndices const> PointIndicesConstPtr;
可以看出在 数据结构 PointIndices 中 定义了点云的header和indices;这里我们不关心header的结构,而indices的结构就是简单的int类型的vector;
所以我们经常见到一些代码直接定义索引的时候直接使用了一下的定义:
1 std::vector<int > points_indices;//int类型的vector类
或者:
1 pcl::IndicesPtr indices(new std::vector <int>);//指向int类型的vector类的空智能指针
若要将智能指针指向定义的 points_indices,需要:
pcl::IndicesPtr index_ptr = boost::make_shared<std::vector<int>>(points_indices);
或者:
pcl::IndicesPtr index_ptr(new std::vector<int>(points_indices));
因为在pcl_base.h中有如下定义:
1 typedef boost::shared_ptr <std::vector<int> > IndicesPtr;
2 typedef boost::shared_ptr <const std::vector<int> > IndicesConstPtr;
PS:
pcl中大量用到了智能指针 share_ptr,shared_ptr允许多个指针指向同一个对象
智能指针的使用方式与普通指针类似:
1.解引用一个智能指针返回它指向的对象;
2.如果在一个条件判断中使用智能指针,效果就是检测它是否为空.
使用智能指针的初始化:
1 //一般的初始化方式
2 shared_ptr<string> pint(new string("normal usage!"));
3 cout<<*pint<<endl;
4
5 //推荐的安全的初始化方式
6 shared_ptr<string> pint1 = make_shared<string>("safe uage!");
7 cout<<*pint1<<endl;
8
先把之前利用到的写一些:
1 int j = 0;
2 std::vector<int > indexs;
3 for (auto i : *normals)
4 {
5 if (i.normal_z < 0.05 && i.normal_z > -0.05)
6 {
7 normals1->points.push_back(i);
8 indexs.push_back(j);
9 }
10 j++;
11 }
12 //打印滤波后将法向量存储在normal1的信息,以及相应的索引
13 std::cout << *normals1 << std::endl;
14 std::cout << indexs.size() << std::endl;
15
16 //索引
17 boost::shared_ptr<std::vector<int>> index_ptr = boost::make_shared<std::vector<int>>(indexs);
18 // Create the filtering object
19 pcl::ExtractIndices<pcl::PointXYZ> extract;
20 // Extract the inliers
21 extract.setInputCloud(cloud_0);
22 extract.setIndices(index_ptr);
23 extract.setNegative(false);//如果设为true,可以提取指定index之外的点云
24 extract.filter(*cloud_1);
25 //法向量滤波后得到的点云信息
26 std::cout << *cloud_1 << std::endl;
上面第17行代码也可以写为:
pcl::IndicesPtr index_ptr = boost::make_shared<std::vector<int>>(indexs);
那么现在有pcl_base.h下的IndicesPtr,为指向int类型的vector的智能指针的索引;
PointIndices.h下的定义的数据结构 PointIndices ;那么将点云进行索引的指针可用以下:
1 pcl::PointIndices index_1;
2 pcl::IndicesPtr index_ptr = boost::make_shared<std::vector<int>>(index_1.indices);
综上所述,索引的使用可以如下所示:
1 std::vector<int > indexs;
2 pcl::PointIndices index_1;
3 pcl::IndicesPtr indices_plane(new std::vector <int>(indexs));
4 pcl::IndicesPtr index_ptr(new std::vector<int>(index_1.indices));
5 pcl::IndicesPtr index_ptr = boost::make_shared<std::vector<int>>(index_1.indices);
6 pcl::IndicesPtr index_ptr = boost::make_shared<std::vector<int>>(indexs);
7 //pcl::IndicesPtr index_ptr = boost::make_shared<std::vector<int>>(index_1);//这个index_1的索引不可用,因为index_1为PointIndices类,只能用上述第5行那样调用
利用ExtractIndices进行索引点云的提取:
1 pcl::ExtractIndices<pcl::PointXYZ> extract;
2 extract.setInputCloud(cloud_0);
3 extract.setIndices(index_ptr);
4 extract.setNegative(false);//如果设为true,可以提取指定index之外的点云
5 extract.filter(*cloud_1);
总结一下,这篇文章主要是解决在PCL使用过程中,用于自定义条件的点云提取,将点云的索引进行相应的存储在 vector<int> 数组中,利用
pcl::IndicesPtr index_ptr = boost::make_shared<std::vector<int>>(points_indices);
或者:
pcl::IndicesPtr index_ptr(new std::vector<int>(points_indices));
进行智能指针的转化,以利用ExtractIndices类中的 setIndices()函数进行点云的提取。
举例如下:
1 //根据想要的点添加到自定义的indices_0的数组中,
2 //std::vector<int> indices_0;
3 pcl::PointIndices indices_0;
4
5 indices_0.indices.push_back(0);
6 indices_0.indices.push_back(10);
7 indices_0.indices.push_back(100);
8 //将自定义的indices_0数组进行智能指针的转化
9 //pcl::IndicesPtr index_ptr_0 = boost::make_shared<std::vector<int>>(indices_0.indices);
10 pcl::IndicesPtr index_ptr_0(new std::vector<int>(indices_0.indices));
11
12 //利用ExtractIndices根据索引进行点云的提取
13 pcl::ExtractIndices<pcl::PointXYZ> extract;
14 extract.setInputCloud(cloud_0);
15 extract.setIndices(index_ptr_0);
16 extract.setNegative(false);//如果设为true,可以提取指定index之外的点云
17 extract.filter(*cloud_1);
18
19 //cloud_1索引0,1,2分别对应与cloud_0索引的0,10,100
20 std::cout << *cloud_1 << std::endl;
21 std::cout << cloud_1->at(0) << std::endl;
22 std::cout << cloud_1->at(1) << std::endl;
23 std::cout << cloud_1->at(2) << std::endl;
24
25 std::cout << *cloud_0 << std::endl;
26 std::cout << cloud_0->at(0) << std::endl;
27 std::cout << cloud_0->at(10) << std::endl;
28 std::cout << cloud_0->at(100) << std::endl;