点云仿射变换—open3d python

1 点云仿射变换

         对于点云来说,仿射变换是将点云中的点按照同一规则变换。仿射变换包含了一组线性变换和一个平移变换。其中,线性变换可以用矩阵左乘来表示。因此,仿射变换可以用矩阵和向量的方式来表达。

         \vec{y} = T\vec{x}+\vec{b}(1)

即:

        \begin{pmatrix} x\\ y\\ z \end{pmatrix}=\begin{bmatrix} t11 & t12 &t13 \\ t21& t22& t23\\ t31& t32 & t33 \end{bmatrix}\begin{pmatrix} x0\\ y0\\ z 0\end{pmatrix}+\begin{pmatrix} b_{x}\\ b_{y}\\ b_{z} \end{pmatrix}(2)

        向量x在向量t上的投影可以表示为

y=\left | x \right |cos\theta =\frac{\vec{t}*\vec{x}}{\left | t\right |}=\frac{t11*x+t12*y+t13*z}{\left | t \right |}(3)

        根据公式(2)和公式(3)可以看到,线性变换过程实际上是数据x在向量空间各个方向上的投影和伸缩。其中,投影的方向由T的行向量来决定,伸缩的倍数由行向量的模长来决定。

        既然是投影,那么在同一条线上的点,投影到另外一个方向上之后应该也是在同一条直线。如果A的行向量存在两个方向相同,即A为奇异矩阵,那么对应的特征分量投影后会重合到同一个方向。这样会导致维度损失了一维,投影后的形状也会发生明显的变形。这样就很形象地说明了投影后的共线性性质,并且通常要求A是非奇异矩阵。

        前面介绍的点云平移和旋转都可以看作是仿射变换的一个特例。对于点云平移来说,仿射变换的矩阵T为0。对于点云旋转来说,仿射变换的矩阵A为旋转矩阵,b为零。

2 open3d投影变换

        open3d中的投影变换为函数为transform,参数为投影变换矩阵T。需要注意的是,open3d中的投影变换不仅仅包括仿射变换,还包括透视投影变换。仿射变换是线性的投影变换,而透视变换是非线性的。因此。open3d中的变换矩阵是4x4大小,而不是3x4。即:

T=\begin{bmatrix} t11 & t12 & t13 &b_{x} \\ t21 & t22 & t23 &b_{y} \\ t31 & t32 & t33 &b_{z} \\ t41& t42 & t43& s \end{bmatrix}

        矩阵T前3行对应仿射变换,最后一行对应透视变换。其中,s可以用来控制缩放系数,表示缩小的倍数。

3 示例程序

        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)  # 窗口高度

4 示例结果

        灰色为原图,蓝色为常规仿射变换,绿色为旋转平移变换,红色为点云缩放结果。

点云仿射变换—open3d python_第1张图片

 python三维点云从基础到深度学习_Coding的叶子的博客-CSDN博客_3d点云 python从三维基础知识到深度学习,将按照以下目录持续进行更新。https://blog.csdn.net/suiyingy/article/details/124017716

更多三维、二维感知算法和金融量化分析算法请关注“乐乐感知学堂”微信公众号,并将持续进行更新。

你可能感兴趣的:(三维点云,python,仿射变换,投影变换,open3d,点云,python)