pcl--第五节 点云表面法线估算

news2024/11/27 22:38:56

估算点云表面法线 *¶

表面法线是几何表面的重要属性,在许多领域(例如计算机图形应用程序)中大量使用,以应用正确的光源以产生阴影和其他视觉效果。

给定一个几何表面,通常很难将表面某个点的法线方向推断为垂直于该点表面的向量。但是,由于我们获取的点云数据集是真实表面上的一组点样本,因此有两种可能性:

  1. 使用表面网格化技术从获取的点云数据集中获取基础表面,然后从网格中计算表面法线;
  2. 使用近似值直接从点云数据集中推断表面法线。

我们将使用后者,即给定点云数据集,直接计算云中每个点的表面法线。

理论基础¶

尽管有许多不同的法线估计方法,我们先了解其中最简单也是最常见的一个,确定表面一点法线的问题近似于估计表面的一个相切面法线的问题,因此转换过来以后就变成一个最小二乘法平面拟合估计问题。

参见官网介绍

算法论文链接RusuDissertation

法线计算¶

image-20200511174327410

image-20200511174656445

// 定义一小块表面区域的协方差矩阵
Eigen::Matrix3f covariance_matrix;
// 定义一小块表面区域的质心坐标
Eigen::Vector4f xyz_centroid;
// 计算质心坐标
pcl::compute3DCentroid(*cloud, xyz_centroid);
// 计算3x3的协方差矩阵
pcl::computeCovarianceMatrix(*cloud , xyz_centroid, covariance_matrix);

法线方向问题¶

没有直接的数学方法可以解决法线的朝向问题,如下边的左图和中图,该数据及来自厨房环境的一部分。很明显图中显示出的法线方向并非朝着一个方向。可以观察右图,对所有法线合并成的扩展高斯图(EGI),也称为法线球体(Normal Sphere),它描述了点云中所有法线的方向。由于数据是2.5维的,即数据只从单一视角获取,其法线也应该仅是一个半球体的扩展高斯图,由于我们没有定下法线的方向,所以这些法线遍布球体。

image-20200516192216734

image-20200516192721669

则可以观察到将所有法线重新定向之后的效果和其对应的扩展高斯图EGI。

选择合适的比例¶

如前所述,需要根据该点的周围点邻域支持,也称为k-neighborhood(k邻域)来估算该点的表面法线。 最近邻估计问题的细节提出了正确的比例因子的问题:给定采样点云数据集,如何选择正确的k(通过pcl::Feature::setKSearch给出)或r(通过pcl::Feature::setRadiusSearch 给出)值来确定点的最近邻居?

image-20200516182945375

这个问题非常重要,并且构成了点特征表示的自动估计(即在没有用户给定阈值的情况下)的限制因素。为了更好地说明此问题,下图显示了选择较小的比例(即较小的r或k)与较大的比例(即较大的r或k)的效果。图的左侧部分描绘了一个合理选择的比例因子,其中估计的表面法线大致垂直于两个平面,并且在整个桌子上可见小的边缘。但是,如果比例因子太大(右侧部分),则相邻对象的集合会覆盖来自相邻表面的较大点,则估计的点要素表示会失真,在两个平面边缘处旋转的曲面法线会被涂抹边缘和压制的精细细节。

_images/normals_different_radii.jpg

_images/curvature_different_radii.jpg

无需赘述太多,只需假设现在必须根据应用所需的详细程度来选择确定点的邻域的比例即可。简而言之,如果杯子的手柄和圆柱部分之间的边缘处的曲率很重要,则比例因子必须足够小以捕获这些细节,否则要大。

默认视点坐标为(0,0,0)(0,0,0),可以使用以下代码修改:

setViewPoint(float vpx, float vpy, float vpx);

计算表面法向量内部伪代码:

// 遍历每个点云P中的点p
for each point p in cloud P 
    // 得到p点的最近邻
    1. get the nearest neighbors of p
    // 计算p点的表面法线n
    2. compute the surface normal n of p
    // 检查n的方向是否指向视点,如果不是则进行反转
    3. check if n is consistently oriented towards the viewpoint and flip otherwise

#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>

int
main() {
    // load point cloud
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile("person.pcd", *cloud);

    // estimate normals
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);

    // Object for normal estimation.
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normalEstimation;
    //normalEstimation.setIndices()
    normalEstimation.setInputCloud(cloud);
    // For every point, use all neighbors in a radius of 3cm.
    normalEstimation.setRadiusSearch(0.03);
    // A kd-tree is a data structure that makes searches efficient. More about it later.
    // The normal estimation object will use it to find nearest neighbors.
    pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
    normalEstimation.setSearchMethod(kdtree);
    // Calculate the normals.
    normalEstimation.compute(*normals);

    // visualize normals
    pcl::visualization::PCLVisualizer viewer("PCL Viewer");
    viewer.setBackgroundColor(0.0, 0.0, 0.5);
    viewer.addPointCloud<pcl::PointXYZ>(cloud, "cloud");
    // 参数int level=2 表示每n个点绘制一个法向量
    // 参数float scale=0.01 表示法向量长度缩放为0.01倍
    viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 2, 0.01, "normals");
    //    viewer.addCoordinateSystem(1.0);

    while (!viewer.wasStopped()) {
        viewer.spinOnce();
    }
    return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1023189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt(day3)

思维导图 小练习 second.h #ifndef SECOND_H #define SECOND_H#include <QWidget> #include<QLabel> #include<QLineEdit> #include<QPushButton> #include<QTimerEvent> #include<QTime> #include<QTextEdit> #include<QTextT…

北京小程序开发-微信小程序开发时间总结

一、双线程模型 渲染线程和逻辑线程 小程序的双线程指的就是渲染线程和逻辑线程&#xff0c;这两个线程分别承担UI的渲染和执行 JavaScript 代码的工作 渲染线程使用 Webview 进行 UI 的渲染呈现。Webview 是一个完整的类浏览器运行环境&#xff0c;本身具备运行 JavaScript…

Shiro 框架基本使用

文章目录 Shiro框架介绍Shiro 基本使用SimpleAccountRealmIniRealmJdbcRealmCustomRealm&#xff08;自定义Realm&#xff09; Shiro框架介绍 Apache Shiro是一个强大且易用的Java安全框架&#xff0c;它执行身份验证、授权、密码和会话管理。Shiro框架通过其三个核心组件&…

网络爬虫-----爬虫的分类及原理

目录 爬虫的分类 1.通用网络爬虫&#xff1a;搜索引擎的爬虫 2.聚焦网络爬虫&#xff1a;针对特定网页的爬虫 3.增量式网络爬虫 4.深层网络爬虫 通用爬虫与聚焦爬虫的原理 通用爬虫&#xff1a; 聚焦爬虫&#xff1a; 爬虫的分类 网络爬虫按照系统结构和实现技术&#…

白鲸开源 X SelectDB 金融大数据联合解决方案公布!从源头解决大数据开发挑战

业务挑战与痛点 随着互联网技术的发展、云计算技术的成熟、人工智能技术的兴起和数字化经济的崛起&#xff0c;数据已成为企业的核心资产。在金融行业中&#xff0c;数字化已成为了支撑各类业务场景的核心力量&#xff0c;包括个人理财、企业融资、股票交易、保险理赔、贷款服…

【Java 基础篇】Java 文件及文件夹操作详解

在Java编程中&#xff0c;文件和文件夹操作是常见的任务之一。你可能需要读取、写入、创建、删除文件或文件夹&#xff0c;以及遍历文件系统中的内容。本文将详细介绍Java中如何执行这些常见的文件和文件夹操作&#xff0c;适用于初学者和基础用户。 1. 文件操作 读取文件内容…

如何显示并管理Python应用的数据?Kendo UI for Angular有妙招!

Angular是Python应用中进行数据管理和显示的一个很好的选择&#xff0c;如果能使用Kendo UI for Angular则可以更进一步。 PS&#xff1a;给大家推荐一个实用组件~Kendo UI for Angular是专业级的Angular UI组件库&#xff0c;不仅是将其他供应商提供的现有组件封装起来&#…

关于IDEA没有显示日志输出?IDEA控制台没有显示Tomcat Localhost Log和Catalina Log 怎么办?

问题描述&#xff1a; 原因是;CATALINA_BASE里面没有相关的文件配置。而之前学习IDEA的时候&#xff0c;把这个文件的位置改变了。导致&#xff0c;最后输出IDEA的时候&#xff0c;不会把日志也打印出来。 检查IDEA配置; D:\work_soft\tomcat_user\Tomcat10.0\bin 在此目录下&…

打造安全的Open RAN

O-RAN架构在为RAN网络引入更多灵活性和最佳实践的同时&#xff0c;也面临着更多的安全风险。本文分别从网元接口通信、RIC安全框架、云原生安全平台等角度全面介绍O-RAN架构在安全方面应该采取的措施。原文: Security in Open RAN 引言 Open RAN是O-RAN联盟在3GPP及其他标准的…

Eureka服务器注册

一。Eureka服务器注册 1.pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mav…

Windows10/11无线网卡WIFI驱动详细下载安装教程

官网下载WIFI驱动 《intel官网》 找到下载Windows 10 and Windows 11* WiFi package drivers 查看详细信息 下载对应操作系统的WIFI驱动 安装驱动&#xff0c;然后重启电脑即可。

SSM - Springboot - MyBatis-Plus 全栈体系(十)

第二章 SpringFramework 五、Spring AOP 面向切面编程 4. Spring AOP 框架介绍和关系梳理 AOP是一种区别于OOP的编程思维&#xff0c;用来完善和解决OOP的非核心代码冗余和不方便统一维护问题&#xff01;代理技术&#xff08;动态代理|静态代理&#xff09;是实现AOP思维编…

云原生之使用Docker部署Nas-Cab个人NAS平台

云原生之使用Docker部署Nas-Cab个人NAS平台 一、Nas-Cab介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Nas-Cab镜像五、部署Nas-Cab5.1 创建挂载目录5.2 创建Nas-Cab容…

前端开发之el-table 表头不换行且宽度自适应

element的table中动态添加表头并设置表头不换行 前言效果图element中使用代码 element-plus中使用:没有了h代码 前言 本次讲解的是elemen和element-plus来通过table的标签render-header来实现的 效果图 element中使用 代码 <template><div><el-table :data&q…

win10修改截图快捷键

用惯了截图快捷键&#xff0c;在新电脑上截图不方便&#xff0c;win10自带截图功能&#xff0c;修改一下系统设置就能使用 点击左下角开始图标&#xff0c;找到Windows 附件&#xff0c;鼠标放到截图工具图标上 点击鼠标右键&#xff0c;选择更多&#xff0c;打开文件位置 跳转…

【排障记录】扩展坞USB 3.0能用而2.0不能用

一、症状表现 日常使用小米的一个扩展坞连接笔记本&#xff0c;平时用来插U盘&#xff0c;没有什么问题&#xff0c;但是今天插了鼠标键盘&#xff0c;发现根本不识别 二、排查过程 目前的连接结构 笔记本C口→type-C延长线→扩展坞A→设备 1.排查笔记本故障 将键盘鼠标插…

MYSQL索引——B+树讲解

B-/B树看 MySQL索引结构 B-树 B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树.它类似普通的平衡二叉树&#xff0c;不同的一点是B-树允许每个节点有更多的子节点。下图是 B-树的简化图. B-树有如下特点: 所有键值分布在整颗树中&#xff1b; 任何一…

Dubbo3应用开发—XML形式的Dubbo应用开发和SpringBoot整合Dubbo开发

Dubbo3程序的初步开发 Dubbo3升级的核心内容 易⽤性 开箱即⽤&#xff0c;易⽤性⾼&#xff0c;如 Java 版本的⾯向接⼝代理特性能实现本地透明调⽤功能丰富&#xff0c;基于原⽣库或轻量扩展即可实现绝⼤多数的 微服务治理能⼒。更加完善了多语言支持&#xff08;GO PYTHON R…

vue基础知识十四:说说你对vue的mixin的理解,有什么应用场景?

一、mixin是什么 Mixin是面向对象程序设计语言中的类&#xff0c;提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类 Mixin类通常作为功能模块使用&#xff0c;在需要该功能时“混入”&#xff0c;有利于代码复用又避免了多继承的复杂 Vue中的mixin 先来看一…

【关于RHCE考试和准备看这一篇就够了】

一、文章大纲 认证机构 课程体系 面向人群 证书有效期 备考学习周期 考试内容 证书领取 证书样例 二、认证机构 RHCE全称为红帽认证工程师&#xff08;Red Hat Certified Engineer&#xff09;&#xff0c;其认证机构为红帽。红帽可以说是Linux发行版中的龙头老大&am…