目录
1.简介
利用set容器进行存储索引,set容器是C++标准库中的一个重要数据结构,它基于红黑树(一种自平衡二叉搜索树)实现,具有以下特性:
1. 唯一性
- set容器中的元素是唯一的,不允许有重复的元素。这是通过set内部自动进行元素比较和去重来实现的。
2. 自动排序
- set容器中的元素会根据一定的排序规则(默认为升序)自动进行排序。这意味着当你向set中插入元素时,它们会自动按照排序规则排好序。
3. 有序性
- 由于set容器是基于红黑树实现的,因此它保持了元素的有序性。这使得set在需要按顺序存储和访问元素的场景中非常有用。
2.示例代码
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/search/kdtree.h>
#include <pcl/common/common.h>
#include <vector>
#include <iostream>
#include <unordered_set>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/extract_indices.h>
using namespace std;
void removeDuplicatePoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, float threshold) {
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
//---------------------KD树半径搜索-------------------
pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
kdtree.setInputCloud(cloud);
vector<int> pointIdxRadiusSearch;
vector<float> pointRadiusSquaredDistance;
set<int> index;
for (size_t i = 0; i < cloud->size(); ++i)
{
pcl::PointXYZ searchPoint = cloud->points[i];
if (kdtree.radiusSearch(searchPoint, threshold, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0)
{
if (pointIdxRadiusSearch.size() != 1)
{
for (size_t j = 1; j < pointIdxRadiusSearch.size(); j++)
{
index.insert(pointIdxRadiusSearch[j]);
}
}
}
}
//-------------------根据索引删除重复的点-------------------
pcl::PointIndices::Ptr outliners(new pcl::PointIndices());
outliners->indices.resize(index.size());
for (int i : index)
{
outliners->indices.push_back(i);
}
cout << "重复点云删除完毕!!!" << endl;
//-------------------提取删除重复点之后的点云--------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
pcl::ExtractIndices<pcl::PointXYZ> extract;
extract.setInputCloud(cloud);
extract.setIndices(outliners);
extract.setNegative(true);
extract.filter(*cloud_filtered);
cloud_filtered->width = cloud_filtered->points.size();
cloud_filtered->height = 1;
cloud_filtered->is_dense = true;
*cloud = *cloud_filtered;
}
int main(int argc, char** argv) {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("cloud_all.pcd", *cloud) == -1) {
PCL_ERROR("Couldn't read file input.pcd \n");
return (-1);
}
int all_point = cloud->points.size();
//距离0.01mm的两个点为重复点
removeDuplicatePoints(cloud, 0.01);
int all_point2 = cloud->points.size();
std::cout << "原始点云中点的个数为:" << all_point << std::endl;
std::cout << "删除的重复点的个数为:" << all_point - all_point2 << std::endl;
/* pcl::io::savePCDFileASCII("output.pcd", *cloud);
std::cout << "Saved " << cloud->width * cloud->height << " data points to output.pcd." << std::endl;*/
//-------------------------可视化-------------------------
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0); // green
viewer->addPointCloud<pcl::PointXYZ>(cloud, single_color, "sample cloud");
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}