文章目录

  • 点云特征
  • 几何变换
  • 点云框线

点云特征

【PointCloud】是open3d中用于点云处理的类,封装了包括几何变换、数据滤波、聚类分割等一系列实用算法,本例中所有例程均基于官方提供的pcd格式数据

# 此行代码后面不再重复引入
import open3d as o3d
pcdDemo = o3d.data.PCDPointCloud()
pcd = o3d.io.read_point_cloud(pcdDemo.path)
# 网速不好,可以下载之后在本地读取
# pcd = o3d.io.read_point_cloud("fragment.pcd")

点云类中封装了一些方法,用以提取点云的特征,调用pcd中的这些方法,其返回值如下

pcd.dimension()             #3 点云维度为3
pcd.has_colors()            # True 点云有颜色
pcd.has_covariances()       # False 对象中不含协方差矩阵
pcd.has_normals()           # True 含法向量
pcd.has_points()            # True  点云中有点
pcd.is_empty()              # False 点云不为空
pcd.get_geometry_type()     # 几何体的类型是点云

通过下面三个函数,可以获取点云对象python点云删除 python处理点云_点云三个坐标的最大值、最小值以及质心。

pcd.get_max_bound() # [3.51953125, 2.76171875, 1.53042805]
pcd.get_min_bound() # [1.15198874, 0.81527287, 0.72640908]
pcd.get_center()    # [2.27219892, 1.73894217, 1.31530002]

对于点云中的某点python点云删除 python处理点云_点云_02,其协方差矩阵为

python点云删除 python处理点云_python点云删除_03

  • 【estimate_covariances】方法可以计算每个点的协方差矩阵。
  • 【compute_mean_and_covariance】可计算整个点云及其协方差的均值。
M_and_C = pcd.compute_mean_and_covariance()

点云类为单点提供了两种距离属性,分别是最邻近距离和Mahalanobis距离,对应的函数分别是 【compute_nearest_neighbor_distance】和 【compute_mahalanobis_distance】。

最邻近距离即当前点和离它最近的其他点的距离;Mahalanobis距离的定义则为

python点云删除 python处理点云_点云_04

其中python点云删除 python处理点云_python点云删除_05为该点对应的协方差矩阵。

几何变换

点云类提供了平移、缩放以及旋转的空间变换方法,可以实现如下转换。

python点云删除 python处理点云_python_06

上图中,从左向右、从上向下从0开始计序,6个点云分别向左和向右进行了平移,其中0号点云是原图;第2号青色的点云进行了缩放;第二排的三个点云则进行了不同程度的旋转。作图函数如下,考虑到点云图床中以左下角为坐标原点,python点云删除 python处理点云_python_07轴向上,python点云删除 python处理点云_python点云删除_08轴向右,所以图像在保存时手动进行了翻转。

from copy import deepcopy

pcds = []
for i in range(6):
    x, y = i%3, i//3
    p = deepcopy(pcd).translate((2.5*x, 2.5*y, 0))
    pcds.append(p)

colors = [(1,0,0), (0,1,1), (0,1,0), (0,0,1), (1,0,1)]
for i,c in enumerate(colors, 1):
    pcds[i].paint_uniform_color(c)


# 2号点云,演示缩放
pcds[2].scale(0.5, center=pcds[2].get_center())

# 3号点云,通过欧拉角旋转
# 采用Euler角的方法生成旋转角,表示绕y轴旋转90°
thEuler = pcds[3].get_rotation_matrix_from_xyz((0,np.pi/2,0))
pcds[3].rotate(thEuler)

# 4号点云,通过轴角法旋转
th = np.array([0, np.pi/3, 0]).T
thAxis = pcds[4].get_rotation_matrix_from_axis_angle(th)
pcds[4].rotate(thAxis)

# 5号点云,通过四元数旋转
# 通过四元数法生成转角,表示绕x轴旋转180°
quart = np.array([0,0,0,1]).T
thQuart = pcds[5].get_rotation_matrix_from_quaternion(quart)
pcds[5].rotate(thQuart)

# 5绘图函数可以输入点云列表
o3d.visualization.draw_geometries(pcds)

【translate】是用于图像平移,其输入数组为python点云删除 python处理点云_点云方向平移的值,考虑到这些操作均将作用于对象本身,所操作之前进行了深拷贝。

【paint_uniform_color】用于更改点云颜色,其输入的数组为RGB三个通道的值。

【scale】用于点云缩放,有两个输入参数,分别是缩放比例和缩放后的位置,本例中,将缩放后的点云放置在原来点云的质心处。

和平移、缩放相比,旋转相对复杂,上例共使用了三个旋转函数来实现。

【get_rotation_matrix_from_xyz】可通过轴角表示法生成旋转角,输入参数为欧拉角,有三个分量,对应横滚、俯仰以及航向这三个方向,代表绕python点云删除 python处理点云_点云轴旋转。考虑一架正在飞行的飞机,以某一时刻前后为x轴、左右为y轴、上下为z轴。则航向角就是飞机前进方向偏离的角度;俯仰角就是飞机头尾姿态的俯仰;横滚角描述的就是飞机翅膀的摆动。

欧拉角用于描述静态角度是没问题的,但表示旋转会导致万向节死锁,简单来说就是飞机的航向角变化90°之后,其横滚轴变成了俯仰轴,导致自由度丢失,而四元数则没有这个顾虑。

设欧拉角为python点云删除 python处理点云_机器学习_11,则四元数可表示为

python点云删除 python处理点云_机器学习_12

点云类中的生成旋转矩阵的方法均为静态方法,可在不建立对象的情况下调用。

在演示变换的过程中调用了三个,其前缀均为 get_rotation_matrix_from_,结尾是 axis_angle表示通过欧拉角生成旋转矩阵;quaternion通过四元数;from_xyz则通过旋转向量。

open3d支持通过不同顺序的xyz数组创建旋转矩阵,由于三个坐标总计有6个组合,故而提供了6个静态方法。例如,针对向量python点云删除 python处理点云_机器学习_13,其创建旋转矩阵的方法为 get_rotation_matrix_from_xyz;对于python点云删除 python处理点云_点云_14,只需将 xyz换为 yxz即可,非常方便记忆。

点云框线

open3d提供了多种生成框线的方法,所谓框线,就是一组将点云完全包裹住的线段。如下图所示,其中左侧绿框为轴对齐边框,顾名思义其框线平行于坐标轴;红框为定向边框,即根据点云自身的性质,寻找合适的边框方向;右侧边框为凸包,即选取点云中最外侧的点连接成一个凸多面体。

python点云删除 python处理点云_python点云删除_15

实现和绘图代码如下

# 定向边框
obb = pcd.get_oriented_bounding_box()
obb.color = [1,0,0]

# 轴对齐边框
aabb = pcd.get_axis_aligned_bounding_box()
aabb.color = [0,1,0]


pcd2 = deepcopy(pcd).translate([3,0,0])
# 凸包
hull, _ = pcd2.compute_convex_hull()
hull_ls = o3d.geometry.LineSet.create_from_triangle_mesh(hull)

o3d.visualization.draw_geometries([pcd, obb, aabb, pcd2, hull_ls])