一、算法原理
1、主要函数
头文件
#include <CGAL/vcm_estimate_normals.h> // Voronoi协方差计算法向量
函数一
void CGAL::vcm_estimate_normals ( PointRange & points,
double offset_radius,
double convolution_radius,
const NamedParameters & np = parameters::default_values()
)
使用Voronoi协方差测量和卷积半径估计点云的法线。输出法线的方向是随机的。
points
:点云offset_radius
:offset_radiusconvolution_radius
:convolution_radiusk
: 邻域点数。np
:下面列出的命名参数中的一个可选序列。
函数二
void CGAL::vcm_estimate_normals ( PointRange & points,
double offset_radius,
unsigned int k,
const NamedParameters & np = parameters::default_values()
)
使用Voronoi协方差测量和卷积半径估计点云的法线。输出法线的方向是随机的。
points
:点云offset_radius
:offset_radiusk
: 进行convolution计算的邻域点数。np
:下面列出的命名参数中的一个可选序列。
二、代码实现
#include <utility> // std::pair
#include <list>
#include <fstream>
#include <CGAL/property_map.h>
#include <CGAL/IO/read_points.h> // 读取点云
#include <CGAL/IO/write_points.h> // 保存点云
#include <CGAL/vcm_estimate_normals.h> // Voronoi协方差计算法向量
#include <CGAL/compute_average_spacing.h> // 计算点云平均密度
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// Types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
// 定义存储点和法线的容器
typedef std::pair<Kernel::Point_3, Kernel::Vector_3> PointVectorPair;
int main(int argc, char* argv[])
{
const std::string fname = CGAL::data_file_path("cgal//kitten.xyz");
const char* output_filename = "cgal//jet_normal.xyz";
// -----------------------------------读取点云------------------------------------
std::list<PointVectorPair> points;
if (!CGAL::IO::read_points(fname, std::back_inserter(points),
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())))
{
std::cerr << "点云读取失败!!! " << fname << std::endl;
return -1;
}
const int nb_neighbors = 18; // K近邻搜索的邻域点数
// -------------使用Voronoi协方差测量和卷积半径估计点云的法线--------------------
double offset_radius = 0.01;
double convolution_radius = 0.02;
CGAL::vcm_estimate_normals(points, offset_radius, convolution_radius,
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())
.normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()));
// ---------------------------------结果保存--------------------------------------
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(6)))
return -1;
return 0;
}