首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Python点云对象:变换与框线

  • 25-02-18 13:41
  • 3144
  • 9445
blog.csdn.net

文章目录

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

点云特征

【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")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

点云类中封装了一些方法,用以提取点云的特征,调用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()     # 几何体的类型是点云
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

通过下面三个函数,可以获取点云对象 x , y , z x,y,z x,y,z三个坐标的最大值、最小值以及质心。

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]
  • 1
  • 2
  • 3

对于点云中的某点 r i r_i ri​,其协方差矩阵为

C i = 1 N ∑ i = 1 N ( r i − r ˉ ) ⋅ ( r i − r ˉ ) T C_i=\frac{1}{N}\sum^N_{i=1}(r_i-\bar r)\cdot(r_i-\bar r)^T Ci​=N1​i=1∑N​(ri​−rˉ)⋅(ri​−rˉ)T

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

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

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

D M ( r i ) = ( r i − r ˉ ) T C i ( r i − r ˉ ) D_M(r_i)=\sqrt{(r_i-\bar r)^TC_i(r_i-\bar r)} DM​(ri​)=(ri​−rˉ)TCi​(ri​−rˉ) ​

其中 C i C_i Ci​为该点对应的协方差矩阵。

几何变换

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

在这里插入图片描述

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

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

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

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

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

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

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

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

设欧拉角为 ( ψ , θ , ϕ ) (\psi,\theta,\phi) (ψ,θ,ϕ),则四元数可表示为

Q = [ cos ⁡ ( ψ / 2 ) 0 0 sin ⁡ ( ψ / 2 ) ] [ cos ⁡ ( θ / 2 ) 0 sin ⁡ ( θ / 2 ) 0 ] [ cos ⁡ ( ϕ / 2 ) sin ⁡ ( ϕ / 2 ) 0 0 ] \bold{Q}=

⎡⎣⎢⎢⎢⎢cos(ψ/2)00sin(ψ/2)⎤⎦⎥⎥⎥⎥
[cos(θ/2)0sin(θ/2)0]
⎡⎣⎢⎢⎢⎢cos(ϕ/2)sin(ϕ/2)00⎤⎦⎥⎥⎥⎥
Q= ​cos(ψ/2)00sin(ψ/2)​ ​[cos(θ/2)​0​sin(θ/2)​0​] ​cos(ϕ/2)sin(ϕ/2)00​ ​

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

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

open3d支持通过不同顺序的xyz数组创建旋转矩阵,由于三个坐标总计有6个组合,故而提供了6个静态方法。例如,针对向量 ( x , y , z ) (x,y,z) (x,y,z),其创建旋转矩阵的方法为 get_rotation_matrix_from_xyz;对于 ( y , x , z ) (y,x,z) (y,x,z),只需将 xyz换为 yxz即可,非常方便记忆。

点云框线

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

在这里插入图片描述

实现和绘图代码如下

# 定向边框
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])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
注:本文转载自blog.csdn.net的微小冷的文章"https://tinycool.blog.csdn.net/article/details/136952524"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top