一、概述
这是加权局部最优投影(WLOP)简化算法的一个实现。WLOP简化算法可以在原始密集点云上产生一组去噪、无异常值、均匀分布的粒子。该算法的核心是一个带密度均匀化项的加权局部最优投影算子。
1、主要函数
头文件
#include <CGAL/wlop_simplify_and_regularize_point_set.h> // WLOP
函数
OutputIterator CGAL::wlop_simplify_and_regularize_point_set ( PointRange & points,
OutputIterator output,
const NamedParameters & np = parameters::default_values()
)
加权局部最优投影(WLOP)简化算法的一个实现。
2、参数解析
** require_uniform_sampling**
计算每个点的密度权重是一个可选的预处理。例如,如下图所示,当require_uniform_sampling
设为false
时,WLOP保留了原始点的内在非均匀采样;如果require_uniform_sampling
设置为true
, WLOP对非均匀采样有弹性,生成分布更均匀的采样点,但计算效率会降低。
neighbor_radius
通常,样本点的邻域至少包括两个相邻样本点的环。使用较小的邻域大小可能无法生成正则化结果,而使用较大的邻域大小会使样本点收缩到局部表面内部(欠拟合)。如果该参数值设置为默认值或小于零值,则该函数会根据点云密度自动估计邻域大小。
二、代码实现
#include <vector>
#include <fstream>
#include <iostream>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/wlop_simplify_and_regularize_point_set.h> // WLOP
#include <CGAL/Simple_cartesian.h>
// types
typedef CGAL::Simple_cartesian<double> Kernel;
int main(int argc, char** argv)
{
const std::string input_filename = CGAL::data_file_path("cgal//points_3//sphere_20k.xyz");
const char* output_filename = "cgal//sphere_20k_WLOPED.xyz";
// ----------------------------读取点云--------------------------------
std::vector<Kernel::Point_3> points;
if (!CGAL::IO::read_points(input_filename, std::back_inserter(points)))
{
std::cerr << "Error: cannot read file " << input_filename << std::endl;
return -1;
}
std::vector<Kernel::Point_3> output;
// ---------------------------参数设置--------------------------------
const double r_percentage = 20;// 保留点所占百分比
const double n_radius = 0.5; // 邻域大小
// ----------------------------滤波-----------------------------------
CGAL::wlop_simplify_and_regularize_point_set<CGAL::Parallel_if_available_tag>
(points, std::back_inserter(output),
CGAL::parameters::select_percentage(r_percentage).
neighbor_radius(n_radius));
// --------------------------结果保存---------------------------------
if (!CGAL::IO::write_points(output_filename, output, CGAL::parameters::stream_precision(8)))
return -1;
return 0;
}