这篇文章的相应数学推到在这个地方,有兴趣的可以瞧一瞧计算两个点集合的旋转矩阵R和T的数学推导
假设有两个点集A和B,且这两个点集合的元素数目相同且一一对应。为了寻找这两个点集之间的旋转矩阵 R R R和转移矩阵 t t t。可以将这个问题建模成如下的公式:
B = R ∗ A + t B = R*A+t B=R∗A+t
为了寻找 R R R和 t t t,通常需要一下三个步骤:

  • 计算点集合的中心点
  • 将点集合移动到原点,计算最优旋转矩阵 R R R
  • 计算转移矩阵 t t t

计算中心点

P = [ x y z ] μ A = 1 N ∑ i = 1 N P A i μ B = 1 N ∑ i = 1 N P B i P = \left[ \begin{matrix} x\\ y \\ z\end{matrix} \right] \\ \mu_A = \frac{1}{N} \sum_{i=1}^{N} P_{A}^i \\ \mu_B = \frac{1}{N} \sum_{i=1}^{N} P_{B}^i P=⎣⎡​xyz​⎦⎤​μA​=N1​i=1∑N​PAi​μB​=N1​i=1∑N​PBi​

将点集合移动到原点,计算最优旋转矩阵 R R R

为了计算旋转矩阵 R R R,需要消除转移矩阵 t t t的影响,所以我们首先需要将点集重新中心化,生成新点集合 A ′ A' A′ 和 B ′ B' B′,然后计算性的点集之间的协方差矩阵:

点集重新中心化

A i ′ = { P A i − μ A } B i ′ = { P B i − μ B } A'_i = \{ P_A^i-\mu_A\} \\ B'_i = \{ P_B^i-\mu_B \} Ai′​={PAi​−μA​}Bi′​={PBi​−μB​}
注意其中的, P A i P_A^i PAi​ 、$ P_B^i$ 、 μ A \mu_A μA​和 μ B \mu_B μB​不是标量是向量。

计算点集之间的协方差矩阵H

H = ∑ i = 1 N A i ′ B i ′ T = ∑ i = 1 N ( P A i − μ A ) ( P B i − μ B ) T H = \sum_{i=1}^{N}A_{i}^{'} {B_{i}^{'}}^T \\ = \sum_{i=1}^{N} (P_A^i-\mu_A)(P_B^i-\mu_B)^T H=i=1∑N​Ai′​Bi′​T=i=1∑N​(PAi​−μA​)(PBi​−μB​)T
通过SVD方法获得矩阵的 U U U、 S S S和 V V V,可以计算点集之间的旋转矩阵 R R R

[ U , S , V ] = S V D ( H ) R = V U T \left[ U,S,V\right] = SVD(H) \\ R = VU^T [U,S,V]=SVD(H)R=VUT

计算转移矩阵 t t t

最后,通过 R R R可以获得转移矩阵 t t t
t = − R × μ A + μ B t = -R\times \mu_A + \mu_B t=−R×μA​+μB​

下面通过python代码编写一个小例子验证一下上面的公式。
下面这个例子,首先通过随机函数生成两个三维点集A,旋转矩阵 R R R和 t t t。通过公式 B = R A T + t B=RA^T+t B=RAT+t获得新的点集B。然后通过上述的方法计算点集A和B之间的旋转矩阵 R ′ R' R′和 t ’ t’ t’,通过公式 B ′ = R ′ A T + t ′ B'=R'A^T+t' B′=R′AT+t′生成新的点集合B’。并计算两个点集合之间的RMSE。

from numpy import *
from math import sqrt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as pltdef rigid_transform_3D(A, B):assert len(A) == len(B)N = A.shape[0];mu_A = mean(A, axis=0)mu_B = mean(B, axis=0)AA = A - tile(mu_A, (N, 1))BB = B - tile(mu_B, (N, 1))H = transpose(AA) * BBU, S, Vt = linalg.svd(H)R = Vt.T * U.Tif linalg.det(R) < 0:print "Reflection detected"Vt[2, :] *= -1R = Vt.T * U.Tt = -R * mu_A.T + mu_B.Treturn R, tif __name__=='__main__':R = mat(random.rand(3,3))t = mat(random.rand(3,1))U,S,Vt = linalg.svd(R)R = U*Vtif linalg.det(R) < 0:Vt[2,:]*=-1R = U*Vtn = 10A = mat(random.rand(n,3))B = R*A.T + tile(t,(1,n))B = B.Tret_R, ret_t = rigid_transform_3D(A,B)A2 = (ret_R*A.T)+ tile(ret_t,(1,n))A2 =A2.Terr = A2-Berr = multiply(err,err)err = sum(err)rmse = sqrt(err/n)print "points A2"print A2print ""print "points B"print Bprint ""print rmsefig = plt.figure()ax=fig.add_subplot(111,projection='3d')ax.scatter(A[:,0],A[:,1],A[:,2])ax.scatter(B[:,0],B[:,1],B[:,2],s=100,marker='x')ax.scatter(A2[:,0],A2[:,1],A2[:,2],s=100,marker= 'o')plt.legend()plt.show()

通过上述代码生成的点集 B ′ B' B′和 B B B中的所有元素如下所示:

points A2
[[0.65985419 1.60528398 1.38340275][0.92739301 1.68052107 0.90692937][0.3398634  1.20672748 1.24869353][0.76117272 1.46282089 1.35712503][0.45657103 1.17657746 0.9993309 ][0.86068981 1.76370772 0.53447625][0.46723696 0.98764769 1.06947054][0.67152812 1.00675099 0.73363394][0.3102857  1.23971537 0.86977264][0.495524   1.10873545 0.93223688]]points B
[[0.65985419 1.60528398 1.38340275][0.92739301 1.68052107 0.90692937][0.3398634  1.20672748 1.24869353][0.76117272 1.46282089 1.35712503][0.45657103 1.17657746 0.9993309 ][0.86068981 1.76370772 0.53447625][0.46723696 0.98764769 1.06947054][0.67152812 1.00675099 0.73363394][0.3102857  1.23971537 0.86977264][0.495524   1.10873545 0.93223688]]

上面小程序的可视化结果如下所示。其中,绿色的圆球和红色的"X"分别表示利用上述方法生成点集 B ′ B' B′和 B B B。蓝色的小圆球表示点集合 A A A。

【引用】

  1. Finding optimal rotation and translation between corresponding 3D points

计算两个对应点集之间的旋转矩阵R和转移矩阵T相关推荐

  1. 利用SVD求得两个对应点集合的旋转矩阵R和转移矩阵t的数学推导

    1.问题描述 给定两个在d维空间中对应的点集合P={p1,p2,-,pn}P = \{ p_1,p_2 ,\dots , p_n\}P={p1​,p2​,-,pn​}和Q={q1,q2,-,qn}Q ...

  2. Java计算两个字符串日期之间的天数差

    Java计算两个字符串日期之间的天数差 调用方法: public static void main(String[] args) throws ParseException {String a = & ...

  3. pandas中使用rolling.corr函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations)、例如,计算两种商品销售额之间的3个月的滚动相关性

    pandas中使用rolling.corr函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations).例如,计算两种商品销售额之间的3个月的滚动相关性 目录

  4. excel中使用CORREL函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations)、例如,计算两种商品销售额之间的3个月的滚动相关性

    excel中使用CORREL函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations).例如,计算两种商品销售额之间的3个月的滚动相关性 目录

  5. R语言使用zoo包中的rollapply函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations)、例如,计算两种商品销售额之间的3个月的滚动相关性

    R语言时间序列数据滚动相关性分析(Rolling correlations).R语言使用zoo包中的rollapply函数计算两个时间序列数据列之间的滚动相关性(Rolling correlation ...

  6. ITK:计算两个3D点之间的距离

    ITK:计算两个3D点之间的距离 内容提要 输出结果 C++实现代码 内容提要 计算两个3D点之间的距离.可以通过更改常量Dimension轻松地将其扩展为ND. 输出结果 Dist: 1.73205 ...

  7. 如何简便计算两个空间向量之间的欧拉角

    版权声明: 1.这篇教程本人曾在微信公众平台发布过,账号为:机构学菜鸟之家.如果哪位朋友在什么地方见过此文,请不要误会~~ 2.本着尊重原创,大家转载的时候请注明出处,此教程编写不易啊~~ 3.由于我 ...

  8. geotools 计算两个经纬度点之间的距离

    geotools 计算两个经纬度点之间的距离 主要的maven依赖 代码实现 最近研究geotools,发现网上的直接搜索相关实现比较少,所以贴出示例代码,方便大家寻找. 主要的maven依赖 < ...

  9. python的datetime举例_Python datetime库计算两个时间点之间的分钟(秒、天)数

    计算两个时间点之间的分钟数 import datetime def minNums(startTime, endTime): '''计算两个时间点之间的分钟数''' # 处理格式,加上秒位 start ...

最新文章

  1. z-index的学习整理转述
  2. [html] 说说你对移动优先布局的理解
  3. Linux 文件或文件夹重命名命令mv
  4. activiti 定时任务和线程池
  5. 各种开源项目/库/工具介绍
  6. 谷歌怎么找ajax请求,谷歌浏览器 - GET ajax请求失败
  7. php7安装详解、,php7安装详解(windows环境)
  8. 自己在使用的漢語辭典
  9. Unity3D 2018安装教程
  10. 【win10专业版】3dmax卸载不干净如何解决
  11. 手机如何打开html文件怎么打开,怎么在手机上打开HTML文件怎么打开
  12. 初始值设置项里有未知的字段ndo_change_mtu
  13. 学会这些方法,扩展磁盘分区还不是轻轻松松?
  14. 制作html版圣诞礼物,10个圣诞礼物制作灵感 创意圣诞卡片手工制作
  15. 基于stm32c8t6的两轮平衡小车 第一篇——物料选购
  16. Hexo速度优化及遇到的问题(gulp4、hexo-neat)
  17. python模型转PMML
  18. 今天项目报错: No operations allowed after connection closed
  19. QNX与Linux两家未来有望独霸车载电子操作系统
  20. 使用pillow生成分享图片

热门文章

  1. 让我思潮翻滚的IBM面试内容
  2. 关于创业,你有什么思路
  3. 单元化架构在金融行业的最佳实践
  4. c语言中生日蛋糕图片大全,简单生日蛋糕图片大全
  5. 2022年11月前端学习笔记
  6. 数据可视化datav使用教程文档1
  7. python 基础100题练习
  8. 如何阅读经济学人的文章
  9. 电脑磁盘里总有个“.Trash-1000”,$recycle.bin文件夹删不掉,好像是装ubuntu双系统留下的。请问怎样删除?
  10. 为什么程序员都找不到对象?