对于点云来说,仿射变换是将点云中的点按照同一规则变换。仿射变换包含了一组线性变换和一个平移变换。其中,线性变换可以用矩阵左乘来表示。因此,仿射变换可以用矩阵和向量的方式来表达。
(1)
即:
(2)
向量x在向量t上的投影可以表示为
根据公式(2)和公式(3)可以看到,线性变换过程实际上是数据x在向量空间各个方向上的投影和伸缩。其中,投影的方向由T的行向量来决定,伸缩的倍数由行向量的模长来决定。
既然是投影,那么在同一条线上的点,投影到另外一个方向上之后应该也是在同一条直线。如果A的行向量存在两个方向相同,即A为奇异矩阵,那么对应的特征分量投影后会重合到同一个方向。这样会导致维度损失了一维,投影后的形状也会发生明显的变形。这样就很形象地说明了投影后的共线性性质,并且通常要求A是非奇异矩阵。
前面介绍的点云平移和旋转都可以看作是仿射变换的一个特例。对于点云平移来说,仿射变换的矩阵T为0。对于点云旋转来说,仿射变换的矩阵A为旋转矩阵,b为零。
open3d中的投影变换为函数为transform,参数为投影变换矩阵T。需要注意的是,open3d中的投影变换不仅仅包括仿射变换,还包括透视投影变换。仿射变换是线性的投影变换,而透视变换是非线性的。因此。open3d中的变换矩阵是4x4大小,而不是3x4。即:
矩阵T前3行对应仿射变换,最后一行对应透视变换。其中,s可以用来控制缩放系数,表示缩小的倍数。
pcd文件请参考:pcd格式点云样例文件-深度学习文档类资源-CSDN下载。
# -*- coding: utf-8 -*-
"""
乐乐感知学堂公众号
@author: https://blog.csdn.net/suiyingy
"""
import open3d as o3d
from copy import deepcopy
import numpy as np
if __name__ == '__main__':
file_path = 'rabbit.pcd'
pcd = o3d.io.read_point_cloud(file_path)
pcd.paint_uniform_color([0.5, 0.5, 0.5])#指定显示为灰色
print(pcd)
#采用欧拉角进行旋转
R = pcd.get_rotation_matrix_from_xyz((0, np.pi/2, 0))#绕y轴旋转90°
#旋转矩阵
R = np.array([[0, 0, 1], [0, 1, 0], [-1, 0, 0]])
# 仿射变换
T = np.array([[1, 0, 0, 20], [0, 1, 1, 20], [0, 0, 1, 0], [0, 0, 0, 1]])
pcd1 = deepcopy(pcd)
pcd1.transform(T)
pcd1.paint_uniform_color([0, 0, 1])#指定显示为蓝色
# 旋转矩阵R+x方向平移20个单位
T = np.array([[0, 0, 1, 20], [0, 1, 0, 0], [-1, 0, 0, 0], [0, 0, 0, 1]]) #旋转矩阵R+x方向平移20个单位
pcd2 = deepcopy(pcd)
pcd2.transform(T)
pcd2.paint_uniform_color([0, 1, 0])#指定显示为绿色
# y方向平移40个单位,并且缩小3倍
T = np.array([[1, 0, 0, 0], [0, 1, 0, 40], [0, 0, 1, 0], [0, 0, 0, 3]]) #y方向平移40个单位,并且缩小3倍
pcd3 = deepcopy(pcd)
pcd3.transform(T)
pcd3.paint_uniform_color([1, 0, 0])#指定显示为红色
# 点云显示
o3d.visualization.draw_geometries([pcd, pcd1, pcd2, pcd3], #点云列表
window_name="投影变换",
point_show_normal=False,
width=800, # 窗口宽度
height=600) # 窗口高度
灰色为原图,蓝色为常规仿射变换,绿色为旋转平移变换,红色为点云缩放结果。
python三维点云从基础到深度学习_Coding的叶子的博客-CSDN博客_3d点云 python从三维基础知识到深度学习,将按照以下目录持续进行更新。https://blog.csdn.net/suiyingy/article/details/124017716
更多三维、二维感知算法和金融量化分析算法请关注“乐乐感知学堂”微信公众号,并将持续进行更新。