PCL法线估计

简介: 平面的法线是垂直于它的单位向量。在点云的表面的法线被定义为垂直于与点云表面相切的平面的向量。表面法线也可以计算点云中一点的法线,被认为是一种十分重要的性质。常常在被使用在很多计算机视觉的应用里面,比如可以用来推出光源的位置,通过阴影与其他视觉影响,表面法线的问题可以近似化解为切面的问题,这个切面的问题又会变成最小二乘法拟合平面的问题解决表面法线估计的问题可以最终化简为对一个协方差矩阵的特征向量和特征值的分析(或者也叫PCA-Principal Component Analysis 主成分分析),这个协方差矩阵是由查询点的最近邻产生的。

平面的法线是垂直于它的单位向量。在点云的表面的法线被定义为垂直于与点云表面相切的平面的向量。表面法线也可以计算点云中一点的法线,被认为是一种十分重要的性质。常常在被使用在很多计算机视觉的应用里面,比如可以用来推出光源的位置,通过阴影与其他视觉影响,表面法线的问题可以近似化解为切面的问题,这个切面的问题又会变成最小二乘法拟合平面的问题

解决表面法线估计的问题可以最终化简为对一个协方差矩阵的特征向量和特征值的分析(或者也叫PCA-Principal Component Analysis 主成分分析),这个协方差矩阵是由查询点的最近邻产生的。对于每个点Pi,我们假设协方差矩阵C如下:


法线提供了关于曲面的曲率信息,这是它的优势。许多的PCL的算法需要我们提供输入点云的法线。为了估计它们,代码分析如下

#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>


int main(int argc,char**argv)
{
//创建点云对象
pcl::PointCloud<pcl::PointXYZ>::Ptr  cloud(new pcl::PointCloud<pcl::PointXYZ>);
//创建法线的对象
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
//读取PCD文件
if(pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1],*cloud) !=0)
{
 return -1;
}
//创建法线估计的对象
pcl::NormalEstimation<pcl::PointXYZ,pcl::Normal> normalEstimation;
normalEstimation.setInputCloud(cloud);
//对于每一个点都用半径为3cm的近邻搜索方式
normalEstimation.setRadiusSearch(0.03);
//Kd_tree是一种数据结构便于管理点云以及搜索点云,法线估计对象会使用这种结构来找到哦啊最近邻点
pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
normalEstimation.setSearchMethod(kdtree);

//计算法线
normalEstimation.compute(*normals);
//可视化
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Normals"));
viewer->addPointCloud<pcl::PointXYZ>(cloud,"cloud");

while(!viewer->wasStopped())
  {
 viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(1000000));
 }

}

试验结果就是运行命令,这里就随便输入一个PCD 文件

可能看不处什么效果*********************

(2)图像积分

积分图像是对有序点云的发现的估计的一种方法。该算法把点云作为一个深度图像,并创建一定的矩形区域来计算法线,考虑到相邻像素关系,而无需建立树形查询结构。因此,它是非常有效的。

#include <pcl/io/pcd_io.h>
#include <pcl/features/integral_image_normal.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>

int
main(int argc, char** argv)
{
    // 点云数据对象
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    // 法线对象
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);

    // 读取文件
    if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0)
    {
        return -1;
    }

    // 法线估计对象
    pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> normalEstimation;
    normalEstimation.setInputCloud(cloud);
    // 法线估计方法: COVARIANCE_MATRIX, AVERAGE_DEPTH_CHANGE, SIMPLE_3D_GRADIENT.
    
    normalEstimation.setNormalEstimationMethod(normalEstimation.AVERAGE_3D_GRADIENT);
    //设置深度变化的阀值
    normalEstimation.setMaxDepthChangeFactor(0.02f);
    // 设置计算法线的区域
    normalEstimation.setNormalSmoothingSize(10.0f);

    // 计算
    normalEstimation.compute(*normals);

    // 可视化
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Normals"));
    viewer->addPointCloud<pcl::PointXYZ>(cloud, "cloud");

    viewer->addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 20, 0.03, "normals");
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
}

结果可视化

具体官方的网址查看pointclouds.org/documentation/tutorials/normal_estimation_using_integral_images.php

 大神请忽略!!!!

微信公众号号可扫描二维码一起共同学习交流

相关文章
|
编解码 算法 数据处理
基于八叉树的空间划分及搜索操作
基于八叉树的空间划分及搜索操作
基于八叉树的空间划分及搜索操作
|
并行计算 算法框架/工具 iOS开发
在RTX3050上安装python3.9、anaconda、pycharm、cuda11.6、cudnn、jupyter等工具的详细步骤和方法
在RTX3050上安装python3.9、anaconda、pycharm、cuda11.6、cudnn、jupyter等工具的详细步骤和方法
532 3
企业微信接入系列-上传临时素材
简述在API接口创建企业群发时上传临时素材的操作
企业微信接入系列-上传临时素材
|
Linux
Linux下安装curl
Linux下安装curl
1787 0
|
7月前
|
人工智能 安全 虚拟化
Cua:Mac用户狂喜!这个开源框架让AI直接接管你的电脑,快速实现AI自动化办公
Cua是一个结合高性能虚拟化与AI代理能力的开源框架,能在Apple Silicon上以接近原生性能运行虚拟机,并让AI直接操作系统应用。
931 17
Cua:Mac用户狂喜!这个开源框架让AI直接接管你的电脑,快速实现AI自动化办公
|
JSON Java 数据格式
UnrecognizedPropertyException: Unrecognized field 解决
UnrecognizedPropertyException: Unrecognized field 解决
406 0
|
缓存 Rust 前端开发
【一起学Rust | 框架篇 | Tauri2.0框架】Tauri2.0环境搭建与项目创建
【一起学Rust | 框架篇 | Tauri2.0框架】Tauri2.0环境搭建与项目创建
1859 0
|
SQL Ubuntu 关系型数据库
如何在云服务器上创建和管理 MySQL 和 MariaDB 数据库
如何在云服务器上创建和管理 MySQL 和 MariaDB 数据库
223 0
|
机器学习/深度学习 人工智能 自然语言处理
深度揭秘:深度学习框架下的神经网络架构进化
从感知机到深度学习的革命,神经网络经历了从简单到复杂的演变。反向传播使多层网络实用化,深度信念网络(DBN)和卷积神经网络(CNN)的兴起,尤其是AlexNet在ImageNet竞赛中的胜利,开启了深度学习黄金时代。ResNet的残差学习解决了深度梯度消失问题。循环神经网络(RNN)、LSTM和GRU改进了序列处理,Transformer模型(如BERT和GPT)引领了自然语言处理的变革。超大规模模型如GPT-3和通义千问展示惊人能力,影响医疗、自动驾驶等多个领域。未来,平衡模型复杂度、计算成本与应用需求将是关键。
729 2
|
存储
使用KD-Tree树查找最近邻点 - 二维
使用KD-Tree树查找最近邻点 - 二维
273 0