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_map
和scan_angle
时,该方法会给出最优结果。只要点集在2.5D扫描线中有序排列,在缺少其中一个或两个属性的情况下,仍然可以生成正确的结果。
- 首先,通过对点进行迭代,获取位于同一扫描线上的点:
- 如果提供了命名参数
scanline_id_map
,则每次id更改时范围都会被切断。 - 如果没有提供扫描线ID映射,回退方法只是简单地在投影xy平面上每次有3个连续点形成锐角时削减范围。这种回退方法给出了次优结果。
- 然后,估计每个点与扫描器位置之间的视线(采集时的估计矢量):
- 如果提供了
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;
}
相关文章:

CGAL 根据扫描线方向和角度对法向量进行重定向
目录一、算法原理1、主要函数二、代码实现一、算法原理 最小生成树对法向量定向的结果在具有许多尖锐特征和遮挡的机载点云数据中结果并不理想。scanline_orient_normals()是专门用于具有扫描线特性的点云法向量重定向的替代方法。它充分利用了某些激光雷达扫描器的LAS特性&…...

一个C#开发的开源的快速启动工具
更多开源项目请查看:一个专注推荐.Net开源项目的榜单 平常计算机安装软件比较多、或者工作涉及的文件比较多,很多人都会直接放在桌面,一方面不安全,还不容易查找,这时候我们往往,都会放在其他硬盘内&#x…...

Paddle项目调试记录
PaddlePaddle是百度公司提出的深度学习框架。近年来深度学习在很多机器学习领域都有着非常出色的表现,在图像识别、语音识别、自然语言处理、机器人、网络广告投放、医学自动诊断和金融等领域有着广泛应用。面对繁多的应用场景,深度学习框架有助于建模者…...
3月11日,30秒知全网,精选7个热点
///微盟集团宣布接入百度文心一言 据介绍,微盟SaaS产品和数字营销服务将与文心一言的技术能力实现深度融合,通过AIGC技术,深化微盟在营销AI创意内容生产、智能营销、智能客服、智能经营等方面的布局 ///T3出行与华为云深化业务合作 双方将在…...
C win32基础学习(四)
上一篇我们已经介绍了关于窗口处理函数的知识。本篇我们说一下注册窗口类,创建窗口和显示窗口的内容。 前文 窗口创建过程 定义WinMain函数 定义窗口处理函数(自定义,处理消息) 注册窗口类(向操作系统写入一些数据) 创建窗口&…...
Java 日期时间API(Java 8及以上)
Java 8及以上版本提供了新的日期时间API,其中包括了LocalDate、LocalTime、LocalDateTime、ZonedDateTime、Duration、Period等类,这些类提供了更加丰富和灵活的日期时间操作方法。 LocalDate LocalDate类表示一个本地日期,不包含时间和时区…...

DHCP的配置
实验目的熟悉DHCP的应用场景掌握DHCP的配置方法实验拓扑DHCP的配置如图15-2所示: 图15-2:DHCP的配置 实验步骤配置IP地址<Huawei>system-view Enter system view, return user view with Ctrl+Z....

JavaWeb14-线程池
目录 1.传统线程的缺点 2.线程池的定义 3.线程池的优点 4.线程池的创建/使用(2类7种) 4.1.通过Executors(执行器)自动创建(6种) ①Executors.newFixedThreadPool:创建⼀个固定⼤⼩的线程池…...

[qiankun+nuxt]子应用请求本地文件报错404
前言 目前公司的前端架构是qiankunnuxt做的微前端项目 问题说明 在子应用中,前端需要模拟一些数据,方便后期演示调整而不需要重新打包 所以将一些数据存储到了本地的json文件中,但是获取时报了404的错误,找不到该文件。 页面报错…...

【Qt网络编程】实现TCP协议通信
文章目录概要:本期主要讲解QT中对于TCP协议通信的实现。一、TCP协议二、Qt中TCP协议处理1.QTcpSocket2.QTcpServer三、Qt实现TCP通信1.客户端2.服务器端结尾概要:本期主要讲解QT中对于TCP协议通信的实现。 一、TCP协议 传输控制协议(TCP&am…...

Webpack打包———处理样式资源
基本使用 本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles&a…...
VP记录:Codeforces Round 857 (Div. 2) A~D
传送门:CF A题 Likes: 这道题的题意很变态,十分的难懂,简直就是一坨shit,这场比赛最后被骂是有原因的 简单来说就是对于一个项目,每一个人都能对此加一或者减一,最后问你这个项目每一时刻最大和最小是多少.题目中只说明了只能点赞后才能取消,并没有解释存在取消操作必存在点…...

Docker常用项目实战演练
docker镜像源的修改 linux环境下编辑 /etc/docker/daemon.json vi /etc/docker/daemon.json #如添加如下网易镜像源 { "registry-mirrors": ["http://hub-mirror.c.163.com"] }docker run命令详细解释 日常工作中用的比较多的是docker run命令ÿ…...
Linux进程间通信-FIFO命名管道
Linux进程间通信-FIFO命名管道 1、概述 管道因为没有名称,所以只用于进程间的亲缘通信。为了克服这一缺点,提出了命名管道(FIFO),又称命名管道、FIFO文件。 FIFO不同于无名管道,它提供与之关联的路径名,该路径名以FIF…...
【Kafka】记录一次基于connect-mirror-maker做的Kafka集群迁移完整过程
文章目录背景环境工具选型实操MM1MM2以MM2集群运行以Standalone模式运行验证附录MM2配置表其他背景 一个测试环境的kafka集群,Topic有360,Partition有2000,部署在虚拟机上,由于多方面原因,要求迁移至k8s容器内&#x…...

实现VOC数据集与COCO数据集格式转换
实现VOC数据集与COCO数据集格式转换2、将voc数据集的xml转化为coco数据集的json格式2、COCO格式的json文件转化为VOC格式的xml文件3、将 txt 文件转换为 Pascal VOC 的 XML 格式<annotation><folder>文件夹目录</folder><filename>图片名.jpg</file…...

常用的密码算法有哪些?
我们将密码算法分为两大类。 对称密码(密钥密码)——算法只有一个密钥。如果多个参与者都知道该密钥,该密钥 也称为共享密钥。非对称密码(公钥密码)——参与者对密钥的可见性是非对称的。例如,一些参与者仅…...

SNS (Simple Notification Service)简介
SNS (Simple Notification Service) 是一种完全托管的发布/订阅消息收发和移动通知服务,用于协调向订阅终端节点和客户端的消息分发。 和SQS (Simple Queue Service)一样,SNS也可以轻松分离和扩展微服务,分布式系统和无服务应用程序…...

JVM初步理解浅析
一、JVM的位置 JVM的位置 JVM在操作系统的上一层,是运行在操作系统上的。JRE是运行环境,而JVM是包含在JRE中 二、JVM体系结构 垃圾回收主要在方法区和堆,所以”JVM调优“大部分也是发生在方法区和堆中 可以说调优就是发生在堆中…...

【巨人的肩膀】MySQL面试总结(一)
💪 目录💪1、什么是ER图2、数据库范式了解吗3、超键、候选键、主键、外键分别是什么?4、为什么不推荐使用外键与级联5、什么是存储过程6、drop、delete与truncate区别7、数据库设计通常分为那几步8、什么是关系型数据库9、什么是SQL10、MySQL…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...

向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...

渗透实战PortSwigger Labs指南:自定义标签XSS和SVG XSS利用
阻止除自定义标签之外的所有标签 先输入一些标签测试,说是全部标签都被禁了 除了自定义的 自定义<my-tag onmouseoveralert(xss)> <my-tag idx onfocusalert(document.cookie) tabindex1> onfocus 当元素获得焦点时(如通过点击或键盘导航&…...
js 设置3秒后执行
如何在JavaScript中延迟3秒执行操作 在JavaScript中,要设置一个操作在指定延迟后(例如3秒)执行,可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法,它接受两个参数: 要执行的函数&…...