一、概述
递归地将点集分割到更小的簇中,直到这些簇的元素小于size
,并且它们的变异因子低于var_max
。
1、主要函数
头文件
#include <CGAL/hierarchy_simplify_point_set.h> // 层次简化算法
函数
PointRange::iterator CGAL::hierarchy_simplify_point_set ( PointRange & points,
const NamedParameters & np = parameters::default_values()
)
递归地将点集分割到更小的簇中,直到这些簇的元素小于size
,并且它们的变异因子低于var_max
。
2、参数解析
size
层次简化算法递归地将点集一分为二,直到每个簇的大小小于参数大小。
var_max
除了尺寸参数,变化参数可以增加单调区域的简化。对于每个聚类,利用协方差矩阵的分类特征值计算一个表面变化测度:
如果团簇共面,这个函数从0 到1/3,如果它是完全各向同性的。如果一个集群的变化大于var_max
,它将被拆分。如果var_max
等于1/3,则该参数没有影响,聚类在整个点集上是规则的。
二、代码实现
#include <vector>
#include <fstream>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/hierarchy_simplify_point_set.h> // 层次简化算法
#include <CGAL/Memory_sizer.h>
#include <CGAL/Timer.h> // 计时
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
int main(int argc, char* argv[])
{
const std::string fname = CGAL::data_file_path("cgal//CSite.xyz");
// --------------------------加载点云----------------------------
std::vector<Kernel::Point_3> points;
if (!CGAL::IO::read_points(fname, std::back_inserter(points)))
{
std::cerr << "点云读取失败!!!" << fname << std::endl;
return -1;
}
std::cout << "从点云数据中读取" << points.size() << "个点。" << std::endl;
// 统计代码运行时间
CGAL::Timer task_timer;
task_timer.start();
// ------------------------层次简化算法--------------------------
points.erase(CGAL::hierarchy_simplify_point_set(points,
CGAL::parameters::size(100)// Max cluster size
.maximum_variation(0.01)), // Max surface variation
points.end());
std::size_t memory = CGAL::Memory_sizer().virtual_size();
std::cout << "采样后还剩" << points.size() << "个点, 算法运行时间" << task_timer.time() << " 秒, "
<< (memory >> 20) << " Mib allocated." << std::endl;
// --------------------------结果保存----------------------------
CGAL::IO::write_points("cgal//CSite_out.xyz", points, CGAL::parameters::stream_precision(17));
return 0;
}
三、结果展示
1、滤波前
2、滤波后