CloudCompare——计算点云的法向量

1.Computing normals on a cloud

  通过菜单栏的'Edit > Normals > Compute'找到该功能。
在这里插入图片描述
设置相关参数
在这里插入图片描述

  如果进行计算的实体对象是点云,那么需要设置以下几个参数:

  • local surface model:选择使用最小二乘拟合平面、二次曲面拟合或三角网。
  • Neighbors->Octree->radius:局部球体邻域的半径。如果设置的太小(即没有足够的点来计算局部模型),那么法线值将默认为(0,0,1)。如果设置的太大,计算的过程可能会很长,结果会很平滑。
  • Orientation:让用户指定一个简单的启发式来设置法线方向(最好是在表面之外)。
  • Orientation->Use preferred orientation :使用如下方式设置点云法线的朝向(+Z与Z轴正方向同向)
    在这里插入图片描述
  • Orientation->Use minimum Spanning Tree :使用最小代价生成树调整点云法线的朝向

注意:

  • 如果没有指定首选方向,或者结果仍然不一致,可能需要使用更高级的算法——‘Normals > Orient Normals > With Minimum Spanning Tree’,来确定法线的方向。
    在这里插入图片描述

  • 在任何情况下,都可能需要使用invert方法对法线字段进行全局反转。
    在这里插入图片描述

2.点云法线计算结果

  法线实体的外观变化取决于光线相对于法线的方向:

  • 对于点云来说,法线向后的点呈现黑色。
    在这里插入图片描述
      保存成txt格式,打开则可以看到在原来XYZ坐标后边多了法向量的值。
    在这里插入图片描述
      保存成pcd格式,使用PCL进行法向量可视化。
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

using namespace std;

int
main(int argc, char** argv)
{
    pcl::PointCloud<pcl::PointNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointNormal>);

    if (pcl::io::loadPCDFile<pcl::PointNormal>("bunny.pcd", *cloud) == -1)
    {
        PCL_ERROR("Could not read file\n");
    }
    //---------------------可视化(含法线)-----------------------------
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("CloudCompare-XYZNormal viewer"));
    viewer->setWindowName("CloudCompare-XYZNormal");
    viewer->addText("CloudCompare-PointNormal", 50, 50, 0, 1, 0, "v1_text");
    viewer->addPointCloud<pcl::PointNormal>(cloud, "CloudCompare-XYZNormal");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "CloudCompare-XYZNormal");
    viewer->addPointCloudNormals<pcl::PointNormal>(cloud, 20, 0.02, "normals");

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

    return 0;
}

在这里插入图片描述

3.反转法线方向(Normals > Invert)

  该工具用来反转所选实体的法线。可以通过Edit > Normals > Invert菜单访问。
法线实体的外观变化取决于光线相对于法线的方向:

  • 对于点云来说,法线向后的点呈现黑色。
  • 对于一个网格(使用默认材质),后向发光的三角形出现在浅蓝色(而前向发光的三角形是绿色)

反转点云的法线方向
在这里插入图片描述
使用PCL可视化
在这里插入图片描述

4. With Minimum Spanning Tree

  这个工具可以通过'Edit > Normals > Orient normals > with Minimum Spanning Tree'菜单访问。
这种方法试图以一致的方式重新定位云的所有法线。它从一个随机的点开始,然后从一个邻居传播到另一个。传播是在最小生成树的帮助下完成的。因此,用户必须指定每个节点上连接的邻居的最大数量(邻居越多,就越准确,但也需要更多的内存和更多的时间)。
使用最小代价生成树调整的结果
在这里插入图片描述

5.With Fast Marching

  这个工具可以通过Edit > Normals > Orient normals > with Fast Marching菜单访问。这种方法试图以一致的方式重新定位云的所有法线。它从一个随机的点开始,然后从一个邻居传播到另一个。传播是通过应用于网格的Fast Marching算法完成的。实际上,这个网格是点云的八叉树,被认为是一个给定的细分级别。因此,用户必须指定此细分级别。问题是找到正确的水平:如果体素分辨率太大(即低水平的细分),传播不是很准确。然而,如果体素分辨率太小(即高水平的细分),可能出现空体素,传播在一次扫描中完成是不可能。
注意:这种方法很快,效率极高。但是不推荐用。

6.HSV colors

  这个工具可以通过Edit > Normals > Convert to > HSV colors菜单访问。用来将点云的法线转换为HSV颜色字段。

H = dip direction, S = dip , V = 1

在这里插入图片描述

7.Dip and Dip direction SFs

  这个工具可以通过Edit > Normals > Convert to > Dip and dip direction SFs菜单访问。
将云的法线转换为两个标量字段:

  • 一个有倾角值
  • 另一个带倾角方向值

注意:角度是以度为单位的。
在这里插入图片描述

8.Clear

  这个工具可以通过Edit > Colors > Clear访问。从选定的实体中移除法线。

9.Computing normals on a mesh

在这里插入图片描述

  • per-vertex:连接到一个顶点的所有三角形的平均法线被分配到这个顶点-光滑的外观,没有保留尖锐的边
  • per triangle:三角形法线被分配到三角形-硬/镶嵌外观,但保留锋利的边缘
    在这里插入图片描述

9.相关链接

[1] PCL 计算点云法向量并显示
[2] PCL 之vtk计算点云模型的法向量

  • 20
    点赞
  • 149
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论
计算点云向量点云处理中重要的一步,可以用于分析点云的曲率、表面变化以及三维重建等应用。以下是一个简单的手写计算点云向量的程序示例: 1. 首先,我们需要导入必要的库,如numpy和sklearn等: import numpy as np from sklearn.neighbors import NearestNeighbors 2. 然后,我们定义一个函数来计算点云向量: def compute_normals(point_cloud, k=20): # 计算最近邻点 nbrs = NearestNeighbors(n_neighbors=k).fit(point_cloud) distances, indices = nbrs.kneighbors(point_cloud) # 初始化向量 normals = np.zeros_like(point_cloud) for i in range(len(indices)): # 计算协方差矩阵 covariance_matrix = np.cov(point_cloud[indices[i]].T) # 计算特征值和特征向量 eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix) # 找到最小特征值的索引 min_eigenvalue_index = np.argmin(eigenvalues) # 提取对应的特征向量作为向量 normals[i] = eigenvectors[:, min_eigenvalue_index] return normals 3. 然后,我们读取点云数据,调用计算向量的函数,并保存结果: point_cloud = np.loadtxt('point_cloud.txt') # 读取点云数据(如果点云数据文件存在的话) normals = compute_normals(point_cloud) # 计算向量 np.savetxt('normals.txt', normals) # 保存向量数据 以上是一个简单的手写计算点云向量的程序示例。注:此示例基于最近邻点计算向量,只是其中的一种方,实际应用中可能会根据具体情况选择其他算

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值