CGAL 点云双边滤波

一、算法原理

  基于点云法线的双边滤波,实现对点云的平滑处理。

1、主要函数

头文件

#include <CGAL/bilateral_smooth_point_set.h>

函数

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

  该函数通过迭代地将每个点投影到最近邻拟合的隐式曲面上,来平滑输入点集。双侧投影根据法线(梯度)信息保留尖锐特征。点位和法线都会被修改。函数返回值为平均点移动误差。这是算法的收敛准则。这个值可以帮助用户决定多少次迭代是足够的。

  • points:包含法向量信息的点云
  • k: 隐式曲面拟合的邻域点数。值越大,结果越平滑。
  • np:下面列出的命名参数中的一个可选序列。

在这里插入图片描述

2、参考文献

H. Huang, S. Wu, M. Gong, D. Cohen-Or, U. Ascher, and H. Zhang. Edge-aware point set resampling. ACM Transactions on Graphics, 32:9:1–9:12, 2013.

二、代码实现

#include <utility> // std::pair
#include <fstream>
#include <CGAL/tags.h>
#include <CGAL/property_map.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/IO/read_points.h>             // 读取点云
#include <CGAL/IO/write_points.h>            // 保存点云
#include <CGAL/bilateral_smooth_point_set.h> // 双边滤波

// Types
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
// 定义一个pair容器用来存储点坐标和法向量
typedef std::pair<Point, Vector> PointVectorPair;

int main(int argc, char* argv[])
{
	// 设置文件读取路径和保存路径
	const std::string input_filename = CGAL::data_file_path("cgal//fin90_with_PCA_normals.xyz");
	const char* output_filename = "cgal//fin90_with_PCA_normals_bilateral_smoothed.xyz";

	// ------------------------------加载含有法线的点云-----------------------------------
	std::vector<PointVectorPair> points;
	if (!CGAL::IO::read_points(input_filename, std::back_inserter(points),
		CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())
		.normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>())))
	{
		std::cerr << "点云读取失败" << input_filename << std::endl;
		return -1;
	}
	// -----------------------------------参数设置----------------------------------------
	int k = 120;                 // 邻域点的个数,点数越多越平滑
	double sharpness_angle = 25; // 控制结果的平滑度,值越大越平滑
	int iter_number = 3;         // 应用投影的次数
	// ------------------------------基于法线的双边滤波----------------------------------
	for (int i = 0; i < iter_number; ++i)
	{
		CGAL::bilateral_smooth_point_set <CGAL::Parallel_if_available_tag>(
			points,
			k,
			CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())
			.normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>())
			.sharpness_angle(sharpness_angle));
	}
	// ------------------------------------结果保存--------------------------------------
	if (!CGAL::IO::write_XYZ(output_filename, points,
		CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())
		.normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>())
		.stream_precision(17)))
		return -1;

	return 0;

}

三、结果展示

白色为原始点云,红色为平滑之后的点云。

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 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、付费专栏及课程。

余额充值