CGAL 使用曲面拟合方法计算点云法向量
2023-09-14 09:15:12 时间
一、算法原理
1、主要函数
头文件
#include <CGAL/jet_estimate_normals.h>
函数
void CGAL::jet_estimate_normals ( PointRange & points,
unsigned int k,
const NamedParameters & np = parameters::default_values()
)
在最近邻上使用射流拟合估计点的范围的法向。输出法线的方向是随机的。
points
:点云k
: 邻域点数。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/jet_estimate_normals.h> // jet计算法向量
#include <CGAL/mst_orient_normals.h> // 最小生成树法线定向
#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//sphere_1k.xyz");
const char* output_filename = "cgal//pca_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;
}
bool knn_search = true;
const int nb_neighbors = 18; // K近邻搜索的邻域点数
if (knn_search == true)
{
// ---------------------使用固定近邻点来计算法线-----------------------------
// 注意:jet_estimate_normals()需要一个范围的点以及属性映射来访问每个点的位置和法线。
CGAL::jet_estimate_normals<CGAL::Parallel_if_available_tag>(points, nb_neighbors,
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())
.normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()));
}
else
{
double spacing = CGAL::compute_average_spacing<CGAL::Parallel_if_available_tag>(points, nb_neighbors,
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>()));
// ---------------------使用固定半径进行法线计算-----------------------------
CGAL::jet_estimate_normals<CGAL::Parallel_if_available_tag>
(points,
0, // 当使用邻域半径时,K=0表示对返回的邻域数量没有限制
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())
.normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>())
.neighbor_radius(2. * spacing)); // 使用平均间距的2倍作为搜索半径
}
// ---------------------------------法线定向--------------------------------------
//注意:mst_orient_normals()需要一个范围的点以及属性映射来访问每个点的位置和法线。
auto unoriented_points_begin = CGAL::mst_orient_normals(points, nb_neighbors,
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>())
.normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()));
// 可选操作: 删除未进行法线定向的点
//points.erase(unoriented_points_begin, points.end());
// ---------------------------------结果保存--------------------------------------
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;
}
相关文章
- 【统计学基础】从可视化到统计检验,比较两个或多个变量分布的方法总结
- 【Android 屏幕适配】屏幕适配通用解决方案 ⑤ ( 自定义组件解决方案 | 自定义 ViewGroup 组件 onMeasure 方法中计算每个子组件坐标数据 | 自定义组件完整代码 )
- 高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据|附代码数据
- Oracle通过时间(分钟)计算有几天几小时几分钟的方法
- jQuery 的 live() 方法对 hover 事件的处理详解编程语言
- 解决Oracle数据库被锁定的方法(oracle数据库被锁定)
- Oracle 判断小数的方法(oracle判断小数)
- abap 中文字符串提取和字节长度计算 (两种方法)详解编程语言
- MySQL中计算某一日期所属周数的方法(mysql日期第几周)
- 龄SQL Server计算人员年龄的实现方法(sqlserver得到年)
- Oracle存储图片路径实现方法研究(oracle存储图片路径)
- MySQL中expx函数的使用方法及作用(mysql中exp(x))
- 缓存使用TP5删除Redis缓存的方法(tp5删除redis)
- 使用 MySQL 计算两张表数据的巧妙方法(mysql 两张表计算)
- Oracle中实现日期计算的方法(oracle中日期的计算)
- Oracle中新建临时表的方法(oracle中新建临时表)
- 在Oracle中计算出年龄的方法(oracle中如何求年龄)
- Oracle中利用周求解方法的实现(oracle中周的计算)
- Oracle中实现两个数之间除法计算的方法(oracle中两个数相除)
- 数计算Oracle中两时间差秒数的实现方法(oracle两时间相差秒)
- Oracle数据库不为空语句的使用方法(oracle不为空语句)
- oracle执行cmd的实现方法
- Asp.net中使用Sqlite数据库的方法
- 在php和MySql中计算时间差的方法
- 用PHP来计算某个目录大小的方法
- 部署到iis后无法加载运行CSS文件的解决方法
- 利用PHP函数计算中英文字符串长度的方法