python:根据旋转平移矩阵求取原始点云或者转换后点云

根据旋转平移矩阵求取原始点云或者转换后点云

  • 原始点云进行旋转平移
    • 示例 1
    • 示例 2
    • 示例 3
    • 示例 4
  • 根据转换后点云及转换矩阵求原始点云
    • 示例 1
    • 示例 2
    • 示例 3
    • 示例 4

原始点云进行旋转平移

转换前的点云可以表示为一个N行3列的矩阵,每一行代表一个点的坐标。我们定义一个旋转矩阵 R 和一个平移矩阵 T。假设转换矩阵为RT,要求转换后的点云,可以通过以下公式推导得到:

新的点云坐标 = R * 原始点云坐标 + T
或者:
转换后点云 = 转换矩阵 * 转换前点云

具体推导过程如下:

  1. 定义转换矩阵T
    RT = [R | t]
    其中R是一个3x3的旋转矩阵,t是一个3x1的平移向量。
    如给定三维空间旋转平移矩阵4*4:

    | r11 r12 r13 tx |
    | r21 r22 r23 ty |
    | r31 r32 r33 tz |
    |  0   0   0  1 |
    

    其中,r11到r33为旋转矩阵的元素,tx、ty、tz为平移向量的元素。

    假设点云中的点为P = (x, y, z, 1),将其转换到B坐标系中的点为P’ = (x’, y’, z’, 1)。
    转换公式为:

    x' = r11*x + r12*y + r13*z + tx
    y' = r21*x + r22*y + r23*z + ty
    z' = r31*x + r32*y + r33*z + tz
    

    其中,x、y、z为点P的坐标,x’、y’、z’为点P’的坐标。

  2. 转换前点云矩阵表示
    转换前点云矩阵表示为N行3列的矩阵P。

  3. 转换后点云计算
    转换后点云可以通过矩阵相乘得到:
    转换后点云 = P * T

示例 1

下面是Python代码实现:

import numpy as np

def transform_points(points, transform_matrix):
    """
    将点云坐标系为A的点云通过转换矩阵转换为坐标系为B的点云
    :param points: 点云坐标系为A的点云,形状为(n, 4),其中n为点的个数,每个点为(x, y, z, 1)
    :param transform_matrix: 转换矩阵,形状为(4, 4)
    :return: 坐标系为B的点云,形状为(n, 4)
    """
    # 添加最后一列,将点云表示为齐次坐标形式
    points_homogeneous = np.concatenate((points, np.ones((points.shape[0], 1))), axis=1)
    # 转换点云坐标
    transformed_points_homogeneous = np.dot(points_homogeneous, transform_matrix.T)
	```
    # 或者也可以写成下面形式
    # transformed_points_homogeneous = np.dot(transform_matrix.T, points_homogeneous).T
    # 可以将RT矩阵拆开成R、t;可写成
    # transformed_points_homogeneous = np.dot(points_homogeneous, R) + t   # 推荐
    # 或者transformed_points_homogeneous = np.dot(R, points_homogeneous.T).T + t  # 会有误差
    # 
    ```
    # 归一化处理,将齐次坐标转换为三维坐标
    transformed_points = transformed_points_homogeneous[:, :3] / transformed_points_homogeneous[:, 3:]
    return transformed_points

使用示例:

points_A = np.array([[1, 0, 0, 1],
                    [0, 1, 0, 1],
                    [0, 0, 1, 1],
                    [1, 1, 1, 1],
                    [2, 2, 2, 1]])

transform_matrix = np.array([[1, 0, 0, 1],
                             [0, 1, 0, 1],
                             [0, 0, 1, 1],
                             [0, 0, 0, 1]])

points_B = transform_points(points_A, transform_matrix)
print(points_B)

输出结果:

[[2. 1. 1.]
 [1. 2. 1.]
 [1. 1. 2.]
 [2. 2. 2.]
 [3. 3. 3.]]

示例 2

首先,假设点云的坐标为 (x, y, z) 和齐次坐标 w,即点云的坐标可以表示为 (x, y, z, w)。

然后,我们定义一个旋转矩阵 R 和一个平移矩阵 T。点云的转换可以表示为:

新的点云坐标 = R * 原始点云坐标 + T

其中,旋转矩阵 R 是一个 3x3 的矩阵,平移矩阵 T 是一个 3x1 的矩阵。对于每个点云坐标 (x, y, z, w),我们得到转换后的坐标 (x’, y’, z’, w’):

x’ = R11 * x + R12 * y + R13 * z + T1
y’ = R21 * x + R22 * y + R23 * z + T2
z’ = R31 * x + R32 * y + R33 * z + T3
w’ = w

现在,我们需要将这个公式转换为代码实现。

首先,导入必要的库:

import numpy as np

然后,定义一个函数来进行点云的转换:

def transform_point_cloud(points, rotation_matrix, translation_matrix):
    # 添加齐次坐标 w
    points = np.hstack((points, np.ones((points.shape[0], 1))))

    # 点云转换
    transformed_points = np.dot(rotation_matrix, points.T).T + translation_matrix

    return transformed_points

在这个函数中,我们首先将点云添加齐次坐标 w。然后,使用矩阵乘法进行点云的转换,并添加平移矩阵。最后,返回转换后的点云。

使用这个函数,我们可以对点云进行转换。假设我们有一个点云矩阵 points,旋转矩阵 rotation_matrix 和平移矩阵 translation_matrix,我们可以这样调用函数:

transformed_points = transform_point_cloud(points, rotation_matrix, translation_matrix)

这样,我们就得到了转换后的点云 transformed_points。

示例 3

要将三维点云通过旋转和平移转换到另一个坐标系,可以使用齐次坐标表示点云和转换矩阵。齐次坐标是将三维坐标和平移合并到一个4维向量中的一种方法。

点云的齐次坐标表示为 [x, y, z, 1]T,其中T表示转置。转换矩阵是一个4*4的矩阵,将点云从一个坐标系转换到另一个坐标系。转换矩阵的形式如下:

R11 R12 R13 T1
R21 R22 R23 T2
R31 R32 R33 T3
0   0   0   1

其中R表示旋转矩阵,T表示平移矩阵。

点云的转换公式如下:

p_new = M * p

其中p_new是转换后的点云,M是转换矩阵,p是原始点云。

下面是Python代码实现:

import numpy as np

# 原始点云
point_cloud = np.array([[x1, y1, z1], [x2, y2, z2], [x3, y3, z3], [x4, y4, z4], [x5, y5, z5]])

# 转换矩阵
transform_matrix = np.array([[R11, R12, R13, T1],
                             [R21, R22, R23, T2],
                             [R31, R32, R33, T3],
                             [0,   0,   0,   1]])

# 添加齐次坐标
point_cloud_homo = np.hstack((point_cloud, np.ones((point_cloud.shape[0], 1))))

# 转换点云
transformed_point_cloud_homo = np.dot(transform_matrix, point_cloud_homo.T).T

# 去除齐次坐标
transformed_point_cloud = transformed_point_cloud_homo[:, :3]

print(transformed_point_cloud)

这样就可以得到转换后的点云 transformed_point_cloud。

示例 4

假设点云为N * 4的矩阵,每行表示一个点的坐标[x, y, z, 1],旋转矩阵为R,平移向量为T。

  1. 公式推导
    将点云矩阵与旋转平移矩阵相乘,得到转换后的点云矩阵:
    P’ = P * [R | T]
    其中,P为原始点云矩阵,P’为转换后的点云矩阵,[R | T]为旋转平移矩阵。

  2. 代码实现
    可以使用NumPy库来进行矩阵运算。

import numpy as np

def transform_point_cloud(point_cloud, rotation_matrix, translation_vector):
    # 将点云矩阵扩展为N * 4矩阵
    point_cloud = np.hstack((point_cloud, np.ones((point_cloud.shape[0], 1))))
    
    # 转换点云
    transformed_point_cloud = np.dot(point_cloud, np.vstack((rotation_matrix, translation_vector)))
    
    return transformed_point_cloud

# 示例点云
point_cloud = np.array([[1, 2, 3],
                       [4, 5, 6],
                       [7, 8, 9]])

# 示例旋转平移矩阵
rotation_matrix = np.array([[1, 0, 0],
                            [0, 1, 0],
                            [0, 0, 1]])
translation_vector = np.array([0, 0, 0])

# 转换点云
transformed_point_cloud = transform_point_cloud(point_cloud, rotation_matrix, translation_vector)

print(transformed_point_cloud)

这样,通过传入点云矩阵、旋转矩阵和平移向量,就可以得到转换后的点云矩阵。

根据转换后点云及转换矩阵求原始点云

要求原始点云N3,已知转换后的点云N3和转换矩阵,可以通过反向计算得到原始点云。

假设转换矩阵为T,原始点云为P,转换后的点云为P’,则有以下关系:

P’ = T * P

其中P和P’都是列向量,T是一个4x4的齐次变换矩阵。

要求原始点云P,可以通过反向计算得到:

P = inverse(T) * P’

其中inverse(T)表示T的逆矩阵。

假设旋转平移矩阵为R,平移向量为T,转换后点云为P_transformed。则可以使用以下代码求得原始点云P_original:

import numpy as np

# 旋转平移矩阵
R = np.array([[r11, r12, r13],
              [r21, r22, r23],
              [r31, r32, r33]])

# 平移向量
T = np.array([tx, ty, tz])

# 转换后点云
P_transformed = np.array([[x1, y1, z1],
                          [x2, y2, z2],
                          [x3, y3, z3],
                          [x4, y4, z4]])

# 求逆矩阵
R_inv = np.linalg.inv(R)

# 原始点云
P_original = np.dot(P_transformed - T, R_inv)  # 推荐

print(P_original)

其中,r11, r12, r13, r21, r22, r23, r31, r32, r33为旋转矩阵的元素,tx, ty, tz为平移向量的元素,x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4为转换后点云的坐标。将上述代码中的矩阵元素和坐标值替换为实际的数值,并运行代码,即可得到原始点云P_original。

示例 1

在Python中,可以使用numpy库来进行矩阵运算。具体代码如下:

import numpy as np

def calculate_original_points(transform_matrix, transformed_points):
    inverse_transform_matrix = np.linalg.inv(transform_matrix)
    original_points = np.dot(inverse_transform_matrix, transformed_points.T).T # 会有误差
    return original_points

示例数据

transform_matrix = np.array([[1, 0, 0, 1],
                             [0, 1, 0, 2],
                             [0, 0, 1, 3],
                             [0, 0, 0, 1]])

transformed_points = np.array([[2, 3, 4],
                               [3, 4, 5],
                               [4, 5, 6]])

original_points = calculate_original_points(transform_matrix, transformed_points)
print(original_points)
输出结果为:
[[-1.  0.  1.]
 [-2. -1.  0.]
 [-3. -2. -1.]]

这样就可以得到原始点云的坐标了。

示例 2

要根据旋转平移矩阵及转换后的点云求得原始点云,需要进行逆运算。

假设有旋转矩阵 R 和平移向量 t,以及转换后的点云 P’。那么原始点云 P 可以通过以下公式计算得到:

P = R^(-1) * (P’ - t)

其中,R^(-1) 表示 R 的逆矩阵。

在 Python 中,可以使用 NumPy 库来进行矩阵操作。下面是一个示例代码:

import numpy as np

# 定义旋转矩阵 R 和平移向量 t
R = np.array([[1, 0, 0],
              [0, 1, 0],
              [0, 0, 1]])  # 假设为单位矩阵
t = np.array([0, 0, 0])  # 假设为零向量

# 定义转换后的点云 P'
P_prime = np.array([[1, 2, 3],
                    [4, 5, 6],
                    [7, 8, 9]])

# 计算旋转矩阵的逆
R_inv = np.linalg.inv(R)

# 计算原始点云 P
P = np.dot(R_inv, (P_prime - t).T).T
# 或者
# P = np.dot((P_prime - t), R_inv)

# 打印原始点云 P
print(P)

这个示例代码中,旋转矩阵 R 被定义为单位矩阵,平移向量 t 被定义为零向量。转换后的点云 P’ 被定义为一个 3x3 的矩阵。

可以根据实际情况修改旋转矩阵 R、平移向量 t 和转换后的点云 P’ 来计算对应的原始点云 P。

示例 3

要根据旋转平移矩阵和转换后的点云,求得原始点云,可以使用以下步骤:

  1. 首先,计算旋转平移矩阵的逆矩阵。假设旋转平移矩阵为R,平移向量为T,则逆矩阵为R_inv。

  2. 然后,对于转换后点云的每个点P’,将其转换为齐次坐标形式,即将其表示为一个3维向量[P’x, P’y, P’z, 1]。

  3. 接下来,利用逆矩阵R_inv将齐次坐标形式的点P’转换为原始点P,即P = R_inv * P’。

  4. 最后,将原始点P去除齐次坐标形式,即将其表示为一个3维向量[Px, Py, Pz]。

以下是一个示例代码:

import numpy as np

# 转换后的点云,shape为(4, 3)
transformed_points = np.array([[1, 2, 3],
                               [4, 5, 6],
                               [7, 8, 9],
                               [10, 11, 12]])

# 旋转平移矩阵,shape为(3, 3)
rotation_matrix = np.array([[0.866, -0.5, 0],
                            [0.5, 0.866, 0],
                            [0, 0, 1]])

# 平移向量,shape为(3, 1)
translation_vector = np.array([[1],
                               [2],
                               [3]])

# 计算逆矩阵
rotation_matrix_inv = np.linalg.inv(rotation_matrix)

# 转换后点云的齐次坐标形式
homogeneous_transformed_points = np.hstack((transformed_points, np.ones((4, 1))))

# 原始点云
original_points = np.dot(rotation_matrix_inv, homogeneous_transformed_points.T)
original_points = original_points.T - np.dot(rotation_matrix_inv, translation_vector)

# 去除齐次坐标形式
original_points = original_points[:, :3]

print(original_points)

这样,原始点云就被计算出来了。注意,这里使用的是3x3的旋转平移矩阵,如果你的矩阵不是这个形式,需要适当修改代码。

示例 4

要根据旋转平移矩阵及转换后的点云来求得原始点云,需要使用逆变换操作。

首先,我们假设旋转平移矩阵为R,平移向量为t,转换后的点云为P_transformed,原始点云为P_original。

逆变换操作可以用以下公式表示:

P_original = R_inv * (P_transformed - t)

其中,R_inv表示矩阵R的逆矩阵。

以下是使用Python代码实现这个操作的示例:

import numpy as np

# 定义旋转平移矩阵R和平移向量t
R = np.array([[1, 0, 0],
              [0, 1, 0],
              [0, 0, 1]])
t = np.array([[1],
              [2],
              [3]])

# 定义转换后的点云P_transformed
P_transformed = np.array([[2, 3, 4],
                          [5, 6, 7],
                          [8, 9, 10],
                          [11, 12, 13]])

# 计算矩阵R的逆矩阵R_inv
R_inv = np.linalg.inv(R)

# 进行逆变换操作,求得原始点云P_original
P_original = np.dot(R_inv, P_transformed.T - t).T

# 打印结果
print(P_original)

这样,就可以根据旋转平移矩阵及转换后的点云求得原始点云。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/580374.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker 入门篇(一)-- 简介与安装教程(Windows和Linux)

一、Docker简介 Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间没有任何接口(类似iPhon…

计算机服务器中了devicdata勒索病毒怎么办?Devicdata勒索病毒解密工具步骤

在这个网络飞速发展的时代,网络为企业的生产运营起到了关键性作用,利用网络可以开展各项工作业务,大大提高了企业生产效率与业务水平,在大家都为网络的便利感到欣慰时,网络数据安全问题,成为众多企业关心的…

河南各地市统计面板数据集(2010-2022年)

数据简介:《河南统计NJ》是一部全面反映河南省经济和社会发展情况的资料性年刊。河南统计年鉴包括行政区划资料、国民经济综合资料、基本单位资料和航空港区资料。 而本篇面板数据则反映了河南省各个地级市的经济、人口、就业、农业、工业、人民生活等等方面的发展…

【Linux系统编程】基础指令(三)

💞💞 前言 hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页&#x…

堆的介绍,实现(c语言实现)

目录 堆的概念 堆的性质: 堆的分类 父子结点的下标关系 堆的向下调整算法 ​编辑小堆 大堆 建堆 堆的向上调整算法 小堆 大堆 堆的基本操作 定义堆 初始化堆 销毁堆 打印堆 堆的插入 堆的删除 大堆(Max Heap)的向下调整算法…

白酒:香型创新在白酒市场竞争中的优势与策略

在香型创新方面展现出明显的市场竞争优势,香型创新不仅满足了消费者对口味多样化的需求,还为酒厂带来了差异化竞争优势。在白酒市场竞争中,实施进一步的香型创新策略对于提升品牌曝光度和市场份额至关重要。 首先,香型创新能够满足…

三篇多模态大模型进展综述

Modality Bridging 综述 多模态大型语言模型(MLLM)可实现基于图像撰写故事和无 OCR 的数学推理,在传统方法中很少见,这表明了通向通用人工智能的潜在路径。 通常人们会在 pair 数据上进行大规模(相对于 instruction t…

【千帆平台】AppBuilder工作流编排新功能体验之创建自定义组件

欢迎来到《小5讲堂》 这是《千帆平台》系列文章,每篇文章将以博主理解的角度展开讲解。 温馨提示:博主能力有限,理解水平有限,若有不对之处望指正! 目录 前言工作流编排组件 创建组件组件界面组件信息 组件画布操作节点…

探索项目管理系统:解析五大功能,洞悉项目成功的关键

项目管理新手往往喜欢埋头苦干,殊不知优秀的项目经理已经熟练运用项目管理系统,让项目规划条理清晰。项目管理系统具备的功能,好用的项目管理系统都有这5大功能。分别是项目WBS分解、项目图表和报表、工时管理、团队协作、任务流程自动化。 一…

(学习日记)2024.04.28:UCOSIII第五十二节:User文件夹函数概览(uC-LIB文件夹)第二部分

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

【中级软件设计师】上午题12-软件工程(1):软件工程模型、敏捷方法、软件需求、系统设计

上午题12-软件工程(1) 1 软件过程1.1 CMM 能力成熟度模型1.1 CMMI (建议直接看思维导图) 2 软件过程模型2.1 瀑布模型2.2 增量模型2.3 演化模型2.3.1 原型模型2.3.2 螺旋模型 2.5 喷泉模型 3 统一过程(UP)模型4 敏捷方…

YOKOGAWA横河手操器维修hart通讯器YHC5150X-01

横河手操器设置注意事项:内藏指示计显示选择与单位设置 有如下 5 种显示模式及单位设置百分比显示、用户设置显示、用户设置和百分比交替显示、输入压力显示、输入压力和百分比交替显示。即应用在当没有输入时操作要求输出为20mA引压方向设置右/左侧高压&#xff0c…

CAS原理及其API原子类

目录 1.CAS及使用 1.1. CAS概念 1.2.原子类的使用 1.3.CAS使用自旋锁 2.CAS的ABA问题 2.1.问题介绍 2.2.ABA问题解决方式 1.CAS及使用 1.1. CAS概念 (1)CAS,其实是一种操作的简称,全称为:Compare and swap。 …

HNU-数据库系统-甘晴void学习感悟

前言 过程坎坷,终局满意。 感觉是学懂了知识,并且拿到了分数这样的学科。 【先把这个位置占下来,之后有时间再补充】 教材如下: 总领 有点忘记了,可参考当时记录的笔记: 数据库系统-甘晴void学习笔记-…

【三】Spring Cloud Ribbon 实战

Spring Cloud Ribbon 实战 概述 一直在构思写一个spring cloud系列文章,一方面是对自己实践经验进行一次完整的梳理,另一方面也是希望能够给初学者一些借鉴,让初学者少走些弯路,看到本系列博客就能够很好的把微服务系列组件用好。…

使用QTcpSocket

(1)客户端每隔10ms向服务器发送一次数字字符串&#xff0c;从0开始。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTcpSocket> #include <QLabel> #include <QTimer> namespace Ui { class MainWindow; }class Mai…

MAVEN的安装与配置

MAVEN的安装与配置 1 简介 1.1 什么是MAVEN? Maven是一个项目构建及管理工具&#xff0c;开发团队几乎不用花多少时间就能够自动完成工程的基础构建配置&#xff0c; Maven 使用了一个标准的目录结构在不同开发工具中也能实现项目结构的统一。Maven提供了清理&#xff0c;编…

【Vue】组件化编程

定义 实现应用中局部功能代码和资源的集合 为什么要用组件化编程? 传统方式编写:依赖关系混乱,不好维护,且代码复用率不高 模块化编写:只关注解决js,复用js,简化js的编写与效率 组件方式编写:好维护、复用率更高、提高运行效率 在组件出现之前,我们开发基本都是用htm…

【综述】DSP处理器芯片

文章目录 TI DSP C2000系列 TMS320F28003X 典型应用 开发工具链 参考资料 TI DSP TI C2000系列 控制领域 TI C5000系列 通信领域 TI C6000系列 图像领域 C2000系列 第三代集成了C28浮点DSP内核&#xff0c;采用了65nm工艺&#xff08;上一代180nm&#xff09; 第四代正在…

PyCharm 无法运行的解决方案

问题&#xff1a; PyCharm 无法运行&#xff0c;该怎么办&#xff1f; 解决方案&#xff1a; 1. 检查 Python 解释器 确保已为 PyCharm 配置正确的 Python 解释器。打开 PyCharm&#xff0c;转到“文件”>“设置”>“项目”>“Python 解释器”。选择所需的 Python …