CGAL 点云离群点剔除

一、主要函数

头文件

#include <CGAL/remove_outliers.h>

函数

PointRange::iterator CGAL::remove_outliers  ( PointRange &  points,  
  unsigned int  k,  
  const NamedParameters &  np = parameters::default_values()  
 ) 

  计算到最近邻居的平均平方距离,并使用平均距离的阈值或选择具有最高平均距离的点的固定百分比来划分点。该方法修改输入点的顺序,以便首先打包所有剩余的点,并在第一个点上返回要删除的迭代器。由于这个原因,它不应该在已排序的容器上调用。
  可以使用两个阈值:threshold_percentthreshold_distance。这个函数返回最小数量的异常值,以便至少满足这些阈值中的一个。这意味着如果threshold_percent=100,则只考虑threshold_distance;如果threshold_distance=0,则只考虑threshold_percent

二、代码实现

#include <vector>
#include <iostream>
#include <CGAL/property_map.h>
#include <CGAL/compute_average_spacing.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/remove_outliers.h> // 点云去噪

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;

int main(int argc, char* argv[])
{
	const std::string fname = CGAL::data_file_path("cgal//oni.pwn");
	// ------------------------------加载点云----------------------------------
	std::vector<Kernel::Point_3> points;
	if (!CGAL::IO::read_points(fname, std::back_inserter(points),
		CGAL::parameters::point_map(CGAL::Identity_property_map<Kernel::Point_3>())))
	{
		std::cerr << "点云读取失败" << fname << std::endl;
		return -1;
	}

	// Removes outliers using erase-remove idiom.
	// The Identity_property_map property map can be omitted here as it is the default value.
	const int nb_neighbors = 24; // 邻域点个数
	// 计算平均密度
	const double average_spacing = CGAL::compute_average_spacing<CGAL::Sequential_tag>(points, nb_neighbors);
	std::vector<Kernel::Point_3>outLier;
	bool outPercent = true; // 离群点百分比是否已知

	if (outPercent == false)
	{
		// -------------------------离群点所占百分比未知---------------------------
		std::vector<Kernel::Point_3>::iterator first_to_remove = CGAL::remove_outliers<CGAL::Parallel_if_available_tag>
			(points, nb_neighbors,
				CGAL::parameters::threshold_percent(100.). // 百分比为100,则只考虑距离
				threshold_distance(2. * average_spacing)); // 距离设置为平均密度的2倍

		std::cerr << (100. * std::distance(first_to_remove, points.end()) / static_cast<double>(points.size()))
			<< "% of the points are considered outliers when using a distance threshold of "
			<< 2. * average_spacing << std::endl;
		outLier.swap(points);
	}
	else
	{
		// --------------------------知道离群点所占百分比----------------------------
		const double removed_percentage = 5.0; // 百分之五的离群点需要移除

		points.erase(CGAL::remove_outliers<CGAL::Parallel_if_available_tag>
			(points,
				nb_neighbors,
				CGAL::parameters::threshold_percent(removed_percentage). // 按最小百分比剔除异常值
				threshold_distance(0.)), // 距离阈值设置为0
			points.end());
		// Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity
		outLier.swap(points);
	}
	
	// -------------------------------------保存结果----------------------------------
	if (!CGAL::IO::write_points("cgal//oni_outlier.xyz", outLier,
		CGAL::parameters::point_map(CGAL::Identity_property_map<Kernel::Point_3>())
		.stream_precision(10)))
	{
		std::cerr << "保存失败!!!" << std::endl;
		return -1;
	}
	
	return 0;
}

三、结果展示

1、滤波前
在这里插入图片描述
2、滤波后
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CGAL(Computational Geometry Algorithms Library)是一个用于计算几何算法的开源库。它提供了许多用于生成和操作点云、线段、多边形等几何实体的功能。 要使用CGAL生成Delaunay三角形,首先需要将点云导入CGAL中。可以通过读取文件或手动输入的坐标来表示点云。然后,使用CGAL中的Delaunay三角形算法构建三角剖分。 Delaunay三角形是一种无重叠的三角剖分,它满足一个性质:对于任何在点云中不属于三角形内部的,其到三角形的最近是唯一的。CGAL库中实现了各种用于创建Delaunay三角形的算法,包括增量构建和依据递归细分的方法。 使用CGAL生成Delaunay三角形的步骤如下: 1. 创建一个点云对象,并将点云中的添加到该对象中。 2. 根据点云数据构建一个Delaunay三角形数据结构,例如使用CGAL中的Delaunay_triangulation_2类。 3. 调用Delaunay三角形数据结构对象的构建方法,如insert()或triangulate(),将点云中的添加到三角形中,并进行三角形的构建。 4. 可选步骤,根据实际需求对三角形进行修改、优化或筛选处理。 5. 根据需要,可以将Delaunay三角形导出到文件或进行可视化展示。 总之,CGAL库提供了方便易用的功能,能够实现从点云数据生成Delaunay三角形的任务。使用CGAL可以快速准确地生成Delaunay三角形,为计算几何问题提供了强大的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

点云侠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值