10.删除点云中的重复点二

目录

1.简介

1. 唯一性

2. 自动排序

3. 有序性

2.示例代码

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;
}

pcl库提供了多种方法来删除点云重复点。其最常用和简单的方法是使用pcl::removeNaNFromPointCloud函数来删除NaN(非数字)点和重复点。该函数将在源点云删除重复的点,并将处理后的点云赋值给另一个点云。以下是使用pcl::removeNaNFromPointCloud函数删除点云重复点的示例代码: ``` pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_in (new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZRGB>); // 假设cloud_in是输入的点云 // 删除NaN点 std::vector<int> indices; pcl::removeNaNFromPointCloud(*cloud_in, *cloud_out, indices); // 删除重复点 std::vector<int> indices_no_duplicate; pcl::PointIndices::Ptr output_indices (new PointIndices); pcl::removeDuplicates(*cloud_out, output_indices->indices, 0.001); pcl::ExtractIndices<pcl::PointXYZRGB> extract; extract.setInputCloud(cloud_out); extract.setIndices(output_indices); pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_no_duplicate (new pcl::PointCloud<pcl::PointXYZRGB>); extract.filter(*cloud_no_duplicate); // cloud_no_duplicate即为处理后的点云,其不包含重复点 ``` 在上述代码,首先使用pcl::removeNaNFromPointCloud函数将源点云的NaN点删除,并保存非NaN点的索引到indices。然后使用pcl::removeDuplicates函数将非NaN点重复删除,并保存非重复点的索引到output_indices->indices。接着使用pcl::ExtractIndices将非重复点提取出来并保存到cloud_no_duplicate。最终得到的cloud_no_duplicate就是处理后的不包含重复点的点云
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别叭叭儿—好好学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值