目录
一、算法原理
1、算法概述
积分图像是对有序点云进行法线估计的一种方法。 该算法将点云视为深度图像,并通过考虑相邻“像素”(点)之间的关系来创建在其上计算法线的某些矩形区域,而无需在诸如KD树的搜索结构上运行查找 。 因此,它的计算效率非常高,通常可在一瞬间计算出法线。 因此,对于从RGB-D传感器获取的有序点云进行实时计算,最好使用此方法。
注意:该方法只适用于有序点云!!!
2、主要函数
void
setNormalEstimationMethod (NormalEstimationMethod normal_estimation_method)
{
normal_estimation_method_ = normal_estimation_method;
}
设置法线估计方法。 目前实现的算法有:
COVARIANCE_MATRIX
:从邻域的协方差矩阵中创建9个积分图去计算一个点的法线。AVERAGE_3D_GRADIENT
: 创建了6个积分图去计算3D梯度里面垂直和水平方向的光滑部分,同时利用两个梯度的叉积来计算法线。AVERAGE_DEPTH_CHANGE
: 创建一个单一的积分图,从平均深度的变化中来计算法线。
void
setBorderPolicy (const BorderPolicy border_policy)
{
border_policy_ = border_policy;
}
设置处理边界的策略。
有:BORDER_POLICY_IGNORE
和BORDER_POLICY_MIRROR
两种策略。
3、参考文献
二、代码实现
from pclpy import pcl
import numpy as np
import open3d as o3d
# ------------------------------加载点云-------------------------------------
cloud = pcl.PointCloud.PointXYZ()
reader = pcl.io.PCDReader()
reader.read("table_scene_mug_stereo_textured.pcd", cloud)
# -----------------------------积分图估计法线---------------------------------
normals = pcl.PointCloud.Normal()
ne = pcl.features.IntegralImageNormalEstimation.PointXYZ_Normal()
ne.setNormalEstimationMethod(ne.AVERAGE_3D_GRADIENT) # 设置估计方法
ne.setBorderPolicy(ne.BORDER_POLICY_MIRROR) # 设置处理边界的策略
ne.setViewPoint(0, 0, 0) # 设置法线定向的视点
ne.setMaxDepthChangeFactor(0.02) # 最大深度变化系数
ne.setNormalSmoothingSize(10.0) # 优化法线方向时考虑邻域大小
ne.setInputCloud(cloud) # 输入点云,必须是有序点云
ne.compute(normals) # 执行法线估计
# ------------------------------保存计算结果---------------------------------
d = np.hstack((cloud.xyz, normals.normals)) # 拼接字段
cloud_with_normal = pcl.PointCloud.PointNormal.from_array(d)
pcl.io.savePCDFileASCII('table_scene_TT.pcd', cloud_with_normal)
# -----------------------------法向量可视化-----------------------------------
pcd = o3d.io.read_point_cloud("table_scene_TT.pcd")
o3d.visualization.draw_geometries([pcd], point_show_normal=False, window_name="法线估计",
width=1024, height=768,
left=50, top=50,
mesh_show_back_face=False) # 可视化点云和法线
三、结果展示
四、相关链接
[1] PCL 使用积分图进行法线估计