PCL只获取点云中一个点的法向量之computePointNormal

2023-11-13

PCL只获取点云中一个点的法向量computePointNormal

最近用点云图做应用的时候想只获取点云中一个点的法向量,然后就在网络上搜索,搜索了半天只能找到一些看似成功,实则语焉不详的文章,甚至是纯照搬、抄袭的文章。所以写下这篇文章供有这个需要的人进行参考。

首先,关于点云图的法向量这个知识点我就不做重复说明,网上有很多人写的很好,大家可以去看一看。这里我重点讲pcl中computePointNormal这个函数的使用。

 computePointNormal (const pcl::PointCloud<PointInT> &cloud, const pcl::Indices &indices,
                          Eigen::Vector4f &plane_parameters, float &curvature)
 computePointNormal (const pcl::PointCloud<PointInT> &cloud, const pcl::Indices &indices,
                          float &nx, float &ny, float &nz, float &curvature)

这是该方法的函数参数说明:

  • cloud是我们要输入的点云图,这里可以输入进你完整的点云图,函数在计算的时候只会计算你想要计算的那个点的法向量。
  • indices是pcl::Indices类型,这个类型实际上你可以看成是std::vector< int >,里面包含的是你要计算的那个点的邻点,这些点可以用KNN进行计算获取到。
  • plane_parameters是得到的结果的平面参数,包含4个变量,分别是一个三维空间中平面方程 A x + B y + C z + D = 0 Ax+By+Cz+D=0 Ax+By+Cz+D=0中的A、B、C、D。而法向量就是(A, B, C)
  • curvature为求得的平面的曲率

第二个函数中,里面的nx, ny, nz和上面的A,B,C等同。

使用这个函数的最难点在于,如何获取一个能够满足函数要求的indices从而能使他成功运行。在文章点击这里ROS社区中指出,我们可以通过使用KNN,PCL中使用名为KdTree的类进行求取。

基本的函数流程:

  1. 实例化一个NormalEstimation的求解器
  2. 实例化一个PointCloud类的法向量
  3. 设置我们要求取的点云中的一个点searchPoint
  4. 使用KdTreesearchPoint中获取indices
  5. 计算并显示

粘贴出代码:

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/cloud_viewer.h>
#include <boost/thread/thread.hpp>

int main (int argc, char** argv)
{
    //加载点云图
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    //这里的点云图设置为你自己的
    if (pcl::io::loadPCDFile<pcl::PointXYZ> ("../../Demo/data/biwi_face_database/model.pcd",
                                           *cloud) == -1) //* load the file
    {
        PCL_ERROR ("Couldn't read file pcd \n");
        return (-1);
    }
    std::cout << "Loaded "
            << cloud->width * cloud->height
            << " data points from pcd."
            << std::endl;

    /*求取法线->对输入的点云图像中的一个点进行法向量求解*/
    //法向量求解器
    pcl::NormalEstimation<pcl::PointXYZ, pcl::PointNormal> pointNormalEstimation;
    //法向量
    pcl::PointCloud<pcl::PointNormal>::Ptr pointNormal(new pcl::PointCloud<pcl::PointNormal>);
    //我们要求解的点,这个点的index你可以自己设置
    pcl::PointXYZ searchPoint = cloud->points[100];
    //KNN
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    //设置KdTree要求解的点云参数
    tree->setInputCloud(cloud);
    //这是K近邻的半径
    float radius = 0.03;
    //关键的数据indices
    std::vector<int> indices;
    //每个点到searchPoint的距离(暂时用不到)
    std::vector<float> distance;
    tree->radiusSearch(searchPoint, radius, indices, distance);

    //输出参数1>平面数据(可以转化为法向量)
    Eigen::Vector4f planeParams;
    //输出参数2>平面曲率
    float curvature;
    //进行单个点的法向量求解
    pointNormalEstimation.computePointNormal(*cloud, indices, planeParams, curvature);
    std::cout << planeParams << std::endl;  //输出平面的数据

    //创建视窗对象,定义标题栏名称“3D Viewer”
    boost::shared_ptr<pcl::visualization::PCLVisualizer>
            viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    //将点云添加到视窗对象中,并定义一个唯一的ID“original_cloud”
    viewer->addPointCloud<pcl::PointXYZ>(cloud, "Cloud");
    //点云附色,三个字段,每个字段范围0-1
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0.5, "Cloud");
    //构造该点对应的法向量
    pointNormal->push_back(pcl::PointNormal(
                                searchPoint._PointXYZ::x, searchPoint._PointXYZ::y, searchPoint._PointXYZ::z,
                                planeParams[0], planeParams[1], planeParams[2],
                                curvature)
                            );
    //将获取到的单个点的法向量添加到图中
    viewer->addPointCloudNormals<pcl::PointNormal>(pointNormal);

    //显示
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }

    return (0);
}

结果显示

单个法向量
近看

法向量结果

至此暂且结束,有问题请在评论留言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PCL只获取点云中一个点的法向量之computePointNormal 的相关文章

随机推荐

  • 微信小程序上线发布流程

    最近花了一天左右的时间学习了下微信小程序的开发 试着练习一把的心态 搞了一个很简单的页面 就当是学习总结吧 学习要点还是挺多的 通过查看官方接口文档 熟悉微信小程序开发工具 工程架构 相比传统页面开发类似 微信小程序也是由js文件 页面布局
  • Qt自定义Delegate实现QTableWidget整行选中圆角矩形高亮效果

    问题背景 参照一个现有的Linux桌面应用 尽可能的模仿它的UI 其中有一个UI效果就是列表整行选中后是一个圆角矩形高亮效果 如下图所示 参考代码 先放代码 实现的思路就是用代理来重绘我们想要的效果 include
  • Socks5代理:跨界电商与游戏产业的爬虫利器与出海战略助推器

    一 Socks5代理 跨界电商与游戏产业的爬虫利器 跨界电商 跨界电商是不同行业或领域之间进行合作的电商模式 企业在拓展全球市场时 需要收集不同领域的市场情报和竞争数据 Socks5代理作为爬虫利器 能够高效稳定地实现数据采集 游戏产业 游
  • Java mail发送相关问题

    一 邮件附件变成bin格式 Java 发送邮件时 邮件附件变成 bin后缀的文件 如下图 出现这个问题 博主查阅了其他博主的文章 大致是附件名称过长或附件名称携带中文 博主代码中采用的是中文加UUID的一个拼接 如下 生成随机的UUID S
  • 【AI实战】llama.cpp 量化部署 llama-33B

    AI实战 llama cpp 量化部署 llama 33B llama cpp 量化介绍 环境配置 安装 llama cpp 拉取 llama cpp 仓库代码 编译llama cpp 生成量化版本模型 模型准备 将上述 pth模型权重转换
  • 大神之路-起始篇

    欢迎关注 WeiyiGeek 公众号 点击 下方卡片 即可关注我哟 设为 星标 每天带你 基础入门 到 进阶实践 再到 放弃学习 涉及 网络安全运维 应用开发 物联网IOT 学习路径 个人感悟 等知识 花开堪折直须折 莫待无花空折枝 作者主
  • 静态路由和动态路由

    display ip routing table 查看全局路由表 路由表匹配规则 最长掩码匹配规则 路由器总是现在最精确 最优的路由项来进行数据转发 路由信息的来源 设备自动发现 直连路由 手动配置 静态路由 通过动态协议生成 动态路由 路
  • HTTP协议 (四) 缓存

    HTTP协议 四 缓存 之前写过一个篇 HTTP协议详解 这次继续介绍HTTP协议中的缓存机制 HTTP协议提供了非常强大的缓存机制 了解这些缓存机制 对提高网站的性能非常有帮助 本文介绍浏览器和Web服务器之间如何处理 浏览器缓存 以及控
  • 【软件开发】从单机到分布式

    从单机到分布式 1 单台服务器应用 问题 由于流量越来越大出现服务器性能问题 2 应用服务器和数据库服务器分离 对架构增加了一台服务器 应用和数据库分别部署到不同的服务器上 对于开发和测试没有任何影响 只需要应用服务器新增一个远程调用数据库
  • python读写文件函数_Python文件读写功能概述,python,函数,总结

    1 python读取csv文件 usr bin python coding UTF 8 df pd read csv filepath usecols func name para value df t df fillna value 对空
  • 文章上传漏洞绕过方式(以php语言为例)

    一 文件上传漏洞原因 由于网站要求 需要用户上传文件 图片 例如头像 保存简单文件上传下载 访问 如果我们将文件上传至web服务器上 并且可以访问到 那么就可以利用小马 对服务器进行操作 或者了解一些信息 因此在上传位置 代码会对上传文件进
  • 解决本地redis连接工具无法连接上宝塔面板的redis

    宝塔安装Redis步奏比较简单 这里我就不讲了 下面来开启一下外网访问 一 第一步需要放开对应安全组中Redis端口 具体端口放开可参考对应服务器厂商的说明文档 二 在宝塔中放行Redis端口 三 修改Redis配置文件将protected
  • 深度学习《图像卷积》

    骚话一下 今天是2020年10月1号 是祖国的71岁生日 也是传统节日中秋节 而我由于工作的安排身在海外不得回家 怀念祖国的乡土 倍加思念远方的亲人 由于疫情 在这里哪里也去不了 只能好好学习 用学习来充实这八天假期 本文完全是为了给CNN
  • 帮我写一个Python代码,利用tensorflow框架实现年龄预测

    import tensorflow as tf import numpy as np 创建模型 model tf keras Sequential model add tf keras layers Dense 128 activation
  • java动态代理中的invoke方法是如何被自动调用的

    一 动态代理与静态代理的区别 1 Proxy类的代码被固定下来 不会因为业务的逐渐庞大而庞大 2 可以实现AOP编程 这是静态代理无法实现的 3 解耦 如果用在web业务下 可以实现数据层和业务层的分离 4 动态代理的优势就是实现无侵入式的
  • centos安装nodejs

    下载地址 https nodejs org en download 本次安装选择的是Source Code 1 下载 wget https nodejs org dist v6 10 0 node v6 10 0 tar gz 当出现 错误
  • Error: Cannot find module ‘vue-loader-v16/package.json‘ 安装vue3.0的项目报错

    vue3 0已经更新在github上好久了 一直没有时间学习 今天好不容易想看一下 根据网上的教程 一步一步的安装 创建项目 启动的时候居然报错 一看这 怀疑是某个依赖没有装上 于是执行了一下 npm install 这次没有报错 但是报了
  • RK3568-GPIO控制

    RK3568 GPIO控制 1 Sysfs接口 实现逻辑 芯片的GPIO由芯片的GPIO控制器来管理 GPIO控制器封装在芯片内部 控制器的驱动芯片厂家已经写好了 RK3568有五组GPIO控制器 每组管理32个引脚 对应 dev下的gpi
  • SQLHelper通用类执行一条返回结果集的SqlCommand命令 使用方法

    SQLHelper cs 通用类 执行一条返回结果集的SqlCommand命令 通过专用的连接字符串 使用参数数组提供参数 使用示例 SqlDataReader r ExecuteReader connString CommandType
  • PCL只获取点云中一个点的法向量之computePointNormal

    PCL只获取点云中一个点的法向量computePointNormal 最近用点云图做应用的时候想只获取点云中一个点的法向量 然后就在网络上搜索 搜索了半天只能找到一些看似成功 实则语焉不详的文章 甚至是纯照搬 抄袭的文章 所以写下这篇文章供