CGAL 点云体素滤波

一、概述

  每个体素中选取一个点代替体素内所有的点。

1、主要函数

头文件

#include <CGAL/grid_simplify_point_set.h> // 体素滤波

函数

PointRange::iterator CGAL::grid_simplify_point_set  ( PointRange &  points,  
  double  epsilon,  
  const NamedParameters &  np = parameters::default_values()  
 )  

二、代码实现

1、方式一

#include <fstream>
#include <cstdlib>
#include <vector>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/grid_simplify_point_set.h> // 体素滤波

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


int main(int argc, char* argv[])
{
    // ---------------------------读取点云--------------------------------
    CGAL::Point_set_3<Point_3> points;

    std::string fname = CGAL::data_file_path("cgal//kitten.xyz");
    std::ifstream stream(fname, std::ios_base::binary);
    if (!stream)
    {
        std::cerr << "Error: cannot read file " << fname << std::endl;
        return -1;
    }

    stream >> points;

    if (points.empty())
    {
        return -1;
    }    
    std::cout << "Read " << points.size() << " point(s)" << std::endl;

    // ---------------------------体素滤波-----------------------------
	auto gsim_it = CGAL::grid_simplify_point_set(points, 0.02);
	points.remove(gsim_it, points.end());

	std::cout << points.number_of_removed_points()
		<< " point(s) removed after simplification." << std::endl;

	points.collect_garbage();


    return 0;
}

2、方式二

#include <vector>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/property_map.h>
#include <CGAL/grid_simplify_point_set.h> // 体素滤波
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;

int main(int argc, char* argv[])
{
	// ---------------------------------加载点云--------------------------------------
	std::vector<Kernel::Point_3> points;
	if (CGAL::IO::read_points("cgal//fin90_with_PCA_normals.xyz", std::back_inserter(points)) == -1)
	{
		std::cerr << "Error: cannot read file" << std::endl;
		return -1;
	}

	std::cout << "从文件中读取" << points.size() << "个点。" << std::endl;
	// ------------------------------体素滤波(返回索引)-----------------------------
	std::vector<std::size_t> indices(points.size());
	for (std::size_t i = 0; i < points.size(); ++i)
	{
		indices[i] = i;
	}

	double cell_size = 0.05; // 格网大小
	auto end = CGAL::grid_simplify_point_set(indices, cell_size, 
		CGAL::parameters::point_map(CGAL::make_property_map(points)));
	std::size_t k = end - indices.begin();
	// 根据索引获取滤波后的点
	std::vector<Kernel::Point_3> out_points(k);

	for (size_t i = 0; i < k; ++i)
	{
		out_points[i] = points[indices[i]];

	}
	std::cout << "滤波后点的个数为:" << out_points.size() << std::endl;
	// ----------------------------------保存结果--------------------------------
	CGAL::IO::write_points("cgal//voxel.xyz", out_points, CGAL::parameters::stream_precision(6));

	return 0;
}

3、方式三

#include <vector>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/property_map.h>
#include <CGAL/grid_simplify_point_set.h> // 体素滤波
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;

int main(int argc, char* argv[])
{
	// ------------------------------加载点云---------------------------------
	std::vector<Kernel::Point_3> points;
	if (CGAL::IO::read_points("cgal//CSite.xyz", std::back_inserter(points)) == -1)
	{
		std::cerr << "Error: cannot read file" << std::endl;
		return -1;
	}

	std::cout << "从文件中读取" << points.size() << "个点。" << std::endl;
	double gridSize = 0.2; // 体素大小
	// ------------------------------体素滤波-------------------------------
	points.erase(CGAL::grid_simplify_point_set(points, gridSize), points.end());
	std::cout << "采样后的点:" << points.size() << std::endl;
	// ------------------------------保存结果-------------------------------
	CGAL::IO::write_points("cgal//CSite1_voxel.xyz", points, CGAL::parameters::stream_precision(6));

	return 0;
}

三、结果展示

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

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、付费专栏及课程。

余额充值