当前位置: 首页 > news >正文

CGAL 根据扫描线方向和角度对法向量进行重定向

目录

  • 一、算法原理
    • 1、主要函数
  • 二、代码实现

一、算法原理

在这里插入图片描述

  最小生成树对法向量定向的结果在具有许多尖锐特征和遮挡的机载点云数据中结果并不理想。scanline_orient_normals()是专门用于具有扫描线特性的点云法向量重定向的替代方法。它充分利用了某些激光雷达扫描器的LAS特性,是处理2.5D城市场景中车载或机载点云法向量方向重定向的最佳选择。

1、主要函数

头文件

#include <CGAL/scanline_orient_normals.h>

scanline_orient_normals()

void CGAL::scanline_orient_normals  ( PointRange &  points,  const NamedParameters &  np = parameters::default_values()  ) 

  通过检查扫描视线方向与当前法线方向的一致性,对点云的法向量进行定向。这个函数要求输入的点是沿着xy平面上对齐的扫描线排序。这种数据通常是通过机载或车载激光雷达设备获得。当提供scanline_id_mapscan_angle时,该方法会给出最优结果。只要点集在2.5D扫描线中有序排列,在缺少其中一个或两个属性的情况下,仍然可以生成正确的结果。

  1. 首先,通过对点进行迭代,获取位于同一扫描线上的点:
  • 如果提供了命名参数scanline_id_map,则每次id更改时范围都会被切断。
  • 如果没有提供扫描线ID映射,回退方法只是简单地在投影xy平面上每次有3个连续点形成锐角时削减范围。这种回退方法给出了次优结果。
  1. 然后,估计每个点与扫描器位置之间的视线(采集时的估计矢量):
  • 如果提供了scan_angle,视线可以直接计算为估计扫描线和扫描角度的组合。
  • 如果没有提供扫scan_angle,扫描仪的位置估计为在xy平面上投影扫描线各点的重心之上。这种回退方法给出了次优结果。
      一旦对每个点的视线进行了估计,就可以通过视点来调整法向量的方向,如果视线和法线向量乘积为正则法向量方向为正的,否则法向量是反的。

二、代码实现

#include <CGAL/Simple_cartesian.h>
#include <CGAL/IO/read_las_points.h>
#include <CGAL/IO/write_ply_points.h>
#include <CGAL/jet_estimate_normals.h>
#include <CGAL/scanline_orient_normals.h>using Kernel = CGAL::Simple_cartesian<double>;using Point_with_info = std::tuple<Kernel::Point_3, Kernel::Vector_3, float, unsigned char>;
using Point_map = CGAL::Nth_of_tuple_property_map<0, Point_with_info>;
using Normal_map = CGAL::Nth_of_tuple_property_map<1, Point_with_info>;
using Scan_angle_map = CGAL::Nth_of_tuple_property_map<2, Point_with_info>;
using Scanline_id_map = CGAL::Nth_of_tuple_property_map<3, Point_with_info>;void dump(const char* filename, const std::vector<Point_with_info>& points)
{std::ofstream ofile(filename, std::ios::binary);CGAL::IO::set_binary_mode(ofile);CGAL::IO::write_PLY(ofile, points, CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()));}int main(int argc, char** argv)
{std::string fname( "cgal//urban.las");std::vector<Point_with_info> points;// ----------------------------------读取las点云--------------------------------------std::cerr << "Reading input file " << fname << std::endl;std::ifstream ifile(fname, std::ios::binary);if (!ifile ||!CGAL::IO::read_LAS_with_properties(ifile, std::back_inserter(points),CGAL::IO::make_las_point_reader(Point_map()),std::make_pair(Scan_angle_map(),CGAL::IO::LAS_property::Scan_angle()),std::make_pair(Scanline_id_map(),CGAL::IO::LAS_property::Scan_direction_flag()))){std::cerr << "Can't read " << fname << std::endl;return -1;}// --------------------------------计算法向量----------------------------------------std::cerr << "Estimating normals" << std::endl;CGAL::jet_estimate_normals<CGAL::Parallel_if_available_tag>(points, 12,CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()));// ---------------------使用扫描角度和扫描方向重定向法线-----------------------------std::cerr << "Orienting normals using scan angle and direction flag" << std::endl;CGAL::scanline_orient_normals(points,CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()).scan_angle_map(Scan_angle_map()).scanline_id_map(Scanline_id_map()));dump("out_angle_and_flag.ply", points);// ---------------------使用扫描方向对点云进行法线定向-------------------------------std::cerr << "Orienting normals using scan direction flag only" << std::endl;CGAL::scanline_orient_normals(points,CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()).scanline_id_map(Scanline_id_map()));dump("out_flag.ply", points);// ---------------------使用扫描角度对点云进行法线定向-------------------------------std::cerr << "Orienting normals using scan angle only" << std::endl;CGAL::scanline_orient_normals(points,CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()).scan_angle_map(Scan_angle_map()));dump("out_angle.ply", points);// -----------------------不使用额外信息的法线定向-----------------------------------std::cerr << "Orienting normals using no additional info" << std::endl;CGAL::scanline_orient_normals(points,CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()));dump("out_nothing.ply", points);return 0;
}
http://www.lryc.cn/news/38018.html

相关文章:

  • 一个C#开发的开源的快速启动工具
  • Paddle项目调试记录
  • 3月11日,30秒知全网,精选7个热点
  • C win32基础学习(四)
  • Java 日期时间API(Java 8及以上)
  • DHCP的配置
  • JavaWeb14-线程池
  • [qiankun+nuxt]子应用请求本地文件报错404
  • 【Qt网络编程】实现TCP协议通信
  • Webpack打包———处理样式资源
  • VP记录:Codeforces Round 857 (Div. 2) A~D
  • Docker常用项目实战演练
  • Linux进程间通信-FIFO命名管道
  • 【Kafka】记录一次基于connect-mirror-maker做的Kafka集群迁移完整过程
  • 实现VOC数据集与COCO数据集格式转换
  • 常用的密码算法有哪些?
  • SNS (Simple Notification Service)简介
  • JVM初步理解浅析
  • 【巨人的肩膀】MySQL面试总结(一)
  • 【数据结构之树】——什么是树,树的特点,树的相关概念和表示方法以及在实际的应用。
  • JavaScript语法
  • 【BIOS/UEFI】HII 基本框架及概述
  • sprintf(...)溢出边界导致程序崩溃的问题
  • 公式推导+dfs简版
  • 论文笔记 | 标准误聚类问题
  • 银行管理系统--课后程序(Python程序开发案例教程-黑马程序员编著-第7章-课后作业)
  • 【18】组合逻辑 - VL18 实现3-8译码器①
  • 2020蓝桥杯真题最长递增 C语言/C++
  • 华为OD机试题 - 寻找连续区间(JavaScript)| 机考必刷
  • 一次疲惫的调试--累了及时透气