使用 Python 从 3D 中的六个点确定齐次仿射变换矩阵

2024-03-17

我得到了三个点的位置:

p1 = [1.0, 1.0, 1.0]
p2 = [1.0, 2.0, 1.0]
p3 = [1.0, 1.0, 2.0]

以及它们转化后的对应物:

p1_prime = [2.414213562373094,  5.732050807568877, 0.7320508075688767]
p2_prime = [2.7677669529663684, 6.665063509461097, 0.6650635094610956]
p3_prime = [2.7677669529663675, 5.665063509461096, 1.6650635094610962]

仿射变换矩阵的形式为

trans_mat = np.array([[…, …, …, …],
                      […, …, …, …],
                      […, …, …, …],
                      […, …, …, …]])

这样与

import numpy as np

def transform_pt(point, trans_mat):
    a  = np.array([point[0], point[1], point[2], 1])
    ap = np.dot(a, trans_mat)[:3]
    return [ap[0], ap[1], ap[2]]

你会得到:

transform_pt(p1, trans_mat) == p1_prime
transform_pt(p2, trans_mat) == p2_prime
transform_pt(p3, trans_mat) == p3_prime

假设变换是齐次的(仅包含旋转和平移),我如何确定这个变换矩阵?

从 CAD 程序中,我知道矩阵是:

trans_mat = np.array([[0.866025403784, -0.353553390593, -0.353553390593, 0],
                      [0.353553390593,  0.933012701892, -0.066987298108, 0],
                      [0.353553390593, -0.066987298108,  0.933012701892, 0],
                      [0.841081377402,  5.219578794378,  0.219578794378, 1]])

我想知道如何找到这个。


仅六个点不足以唯一地确定仿射变换。但是,根据您之前在问题中提出的问题(在删除之前不久)以及你的评论 https://stackoverflow.com/questions/27546081/determining-transformation-matrix-from-six-points-in-python/27547597#comment43823906_27547597,看来您不仅仅是在寻找仿射变换,而是在寻找齐次仿射变换.

罗布约翰的回答 https://math.stackexchange.com/a/222170提供问题的解决方案。虽然它解决了一个有很多点的更一般的问题,但 6 个点的解决方案可以在答案的最底部找到。我将在这里以对程序员更友好的格式转录它:

import numpy as np

def recover_homogenous_affine_transformation(p, p_prime):
    '''
    Find the unique homogeneous affine transformation that
    maps a set of 3 points to another set of 3 points in 3D
    space:

        p_prime == np.dot(p, R) + t

    where `R` is an unknown rotation matrix, `t` is an unknown
    translation vector, and `p` and `p_prime` are the original
    and transformed set of points stored as row vectors:

        p       = np.array((p1,       p2,       p3))
        p_prime = np.array((p1_prime, p2_prime, p3_prime))

    The result of this function is an augmented 4-by-4
    matrix `A` that represents this affine transformation:

        np.column_stack((p_prime, (1, 1, 1))) == \
            np.dot(np.column_stack((p, (1, 1, 1))), A)

    Source: https://math.stackexchange.com/a/222170 (robjohn)
    '''

    # construct intermediate matrix
    Q       = p[1:]       - p[0]
    Q_prime = p_prime[1:] - p_prime[0]

    # calculate rotation matrix
    R = np.dot(np.linalg.inv(np.row_stack((Q, np.cross(*Q)))),
               np.row_stack((Q_prime, np.cross(*Q_prime))))

    # calculate translation vector
    t = p_prime[0] - np.dot(p[0], R)

    # calculate affine transformation matrix
    return np.column_stack((np.row_stack((R, t)),
                            (0, 0, 0, 1)))

对于您的示例输入,这将恢复与您从 CAD 程序获得的矩阵完全相同的矩阵:

>>> recover_homogenous_affine_transformation(
        np.array(((1.0,1.0,1.0),
                  (1.0,2.0,1.0),
                  (1.0,1.0,2.0))),
        np.array(((2.4142135623730940, 5.732050807568877, 0.7320508075688767),
                  (2.7677669529663684, 6.665063509461097, 0.6650635094610956),
                  (2.7677669529663675, 5.665063509461096, 1.6650635094610962))))
array([[ 0.8660254 , -0.35355339, -0.35355339,  0.        ],
       [ 0.35355339,  0.9330127 , -0.0669873 ,  0.        ],
       [ 0.35355339, -0.0669873 ,  0.9330127 ,  0.        ],
       [ 0.84108138,  5.21957879,  0.21957879,  1.        ]])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Python 从 3D 中的六个点确定齐次仿射变换矩阵 的相关文章

  • 多个对象以某种方式相互干扰[原始版本]

    我有一个神经网络 NN 当应用于单个数据集时 它可以完美地工作 但是 如果我想在一组数据上运行神经网络 然后创建一个新的神经网络实例以在不同的数据集 甚至再次同一组数据 上运行 那么新实例将产生完全错误的预测 例如 对 XOR 模式进行训练
  • 调试VS 2005提示“操作不支持”

    我一直在调试 VS 2005 并将 启动外部程序 设置为 C Program Files Microsoft Visual Studio 10 0 Common7 IDE devenv exe 但按 F5 后出现此错误 尝试运行项目时出错
  • 使用ssl和socket的python客户端身份验证

    我有一个 python 服务器 需要客户端使用证书进行身份验证 我如何制作一个客户端脚本 使用客户端证书由 python 中的服务器使用 ssl 和套接字模块进行身份验证 有没有仅使用套接字和 ssl 而不扭曲的示例 from OpenSS
  • Android Jasper 报告

    Jasper Reporting 可以集成到 Android 应用程序中吗 我正在尝试从 jrxml 文件生成 PDF CSV 文本和 XLS 报告 但是 我没有看到 Android SDK 支持 net sf jasperreports
  • Bootstrap 3 / 显示模式不适用于 javascript 方式

    我用Modal http getbootstrap com javascript modalsBootstrap 3 0 的功能 我有这个代码 a href myNestedContent Open the modal containing
  • 如何为不同操作系统/Python 版本编译 Python C/C++ 扩展?

    我注意到一些成熟的Python库已经为大多数架构 Win32 Win amd64 MacOS 和Python版本提供了预编译版本 针对不同环境交叉编译扩展的标准方法是什么 葡萄酒 虚拟机 众包 我们使用虚拟机和Hudson http hud
  • 在 VS2008 的 XAML 编辑器中禁用 Intellisense?

    有没有办法在 Visual Studio 2008 的 XAML 编辑器中禁用 Intellisense 打字时通常会消耗很大的性能 有时我会等待十秒或更长时间 直到列表自动弹出 似乎在 选项 gt 文本编辑器 gt XAML 中 Inte
  • 查询联系人 - 有时返回空游标

    我正在尝试查询联系人的显示名称 Override public void onActivityResult int requestCode int resultCode Intent data switch requestCode case
  • Swing:创建可拖动组件...?

    我在网上搜索了可拖动 Swing 组件的示例 但我发现示例不完整或不起作用 我需要的是一个摇摆组件那可以是dragged通过鼠标 在另一个组件内 被拖拽的时候 应该已经 改变它的位置 而不仅仅是 跳 到目的地 我很欣赏无需非标准 API 即
  • RichFaces 应用程序,我应该使用 rich:dataTable 还是 jQGrid,优缺点吗?

    继从here https stackoverflow com questions 3899649 ok to wrap jsf components generated html with own divs using jquery aft
  • 如何调试 Gulp 任务?

    如何调试我的中定义的 gulp 任务gulpfile js使用诸如 Google Chrome 调试器之类的调试器逐行单步执行任务的代码 对于 Node js 6 3 版本 您可以使用 inspect flag https nodejs o
  • 在 javascript 中使用 xPath 解析具有默认命名空间的 XML

    我需要创建一个 XML xPath 解析器 所有解析都必须在客户端进行 使用 JavaScript 我创建了一个 javascript 来执行此操作 在默认名称空间发挥作用之前 一切看起来都正常 我根本无法查询具有默认命名空间的 XML 我
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost
  • 在门户中查看 Azure WebJob 计划?

    我创建了一个简单的 Azure WebJob 并通过 Visual Studio 集成制定了每天运行一次的计划 我已经部署了 WebJob 并看到它列在我在 Azure 上的应用程序中 schema http schemastore org
  • 嵌入式二进制资源 - 如何枚举嵌入的图像文件?

    我按照中的说明进行操作这本书 http www apress com book view 9781430225492 关于资源等的章节 我不太明白的是 如何替换它 images Add new BitmapImage new Uri Ima
  • 小于或等于

    使用暂停命令我发现错误位于此代码的第一行 if choice 1 if energy gt m2enc set a enemhp enemhp m1hpd earmr pause set a energy energy m1enc set
  • 给定文档,选择相关片段

    当我在这里提出问题时 自动搜索返回的问题的工具提示给出了问题的前一点 但其中相当一部分没有给出任何比理解问题更有用的文本 标题 有谁知道如何制作一个过滤器来删除问题中无用的部分 我的第一个想法是修剪仅包含某个列表中的单词的任何前导句子 例如
  • 从 npm 脚本运行时,eslint 不会报告任何错误

    我已经使用 npm init eslint config 安装了带有 typescript 的 eslint 然后将 lint 脚本添加到我的 package json 中 但是当我运行 npm script lint npm run li
  • 无法将 /root/.rnd 加载到 RNG 中

    我想使用 Windows Open SSL 生成服务器证书 当我运行此命令行时 出现此错误 我应该怎么办 Command openssl req new x509 days 3650 key ca key out ca crt Error
  • Android Espresso - 如果未选中,请单击复选框

    I have onView withId R id check box perform click 但我只想在尚未选中该复选框时执行此操作 我怎样才能在浓缩咖啡中做到这一点 我还想根据其之前的状态来切换复选框 开关 起初 我尝试用此方法打开

随机推荐