SVD求解两组多维点之间的欧式变换矩阵,及halcon代码实现

news/2024/11/2 7:36:58/

之前研究了二维点的仿射变换,用解矩阵的方式求解了两组二维点之间的变换矩阵。

学习了下SVD,看到可以用SVD求解两组多维点之间的欧式变换矩阵,当然也是个最优化问题。

这里的变换只有平移和旋转,没有缩放。

一、先说结论:

现在有两组点(2d,3d,或者多维都可以),

P=\left \{ {p_{1},...p_{n}}\right \},P^{'}=\left \{ {p^{'}_{1},...p^{'}_{n}}\right \},

 需要找到R和t,使得

p_{i}=Rp^{'}_{i}+t

一般没有完美解,需要找到最优解R和t,使得P'变换后的点和P误差最小。

操作步骤:

1,,求两组点质心位置p,p^{'},得到两组点去质心坐标

q_{i}=p_{i}-p,q^{'}_{i}=p^{'}_{i}-p^{'}

2,得到矩阵W

W=\sum_{i=1}^{n}q_{i}q^{'T}_{i}

3,对W进行奇异值分解

W=U\Sigma V^{T}

4.得到最优R和T

R=VU^{T}

T=p-Rp^{'}

二、用halcon代码来实现下

举例测试两组点P和Q

PX := [0.2,0.4,0.2,0.3]
PY := [0.4,0.6,0.8,0.6]
PZ := [0.6,0.8,0.6,0.5]
QX := [0.25,0.44,0.61,0.3]
QY := [0.32,0.56,0.82,0.4]
QZ := [0.4,0.18,0.6,0.51]

halcon代码实现如下

*两组3d点P和Q,每组4个点PX := [0.2,0.4,0.2,0.3]
PY := [0.4,0.6,0.8,0.6]
PZ := [0.6,0.8,0.6,0.5]
QX := [0.25,0.44,0.61,0.3]
QY := [0.32,0.56,0.82,0.4]
QZ := [0.4,0.18,0.6,0.51]*对P和Q去质心化处理
create_matrix (3, |PX|, [PX,PY,PZ], P)
mean_matrix (P, 'rows', PMean)
create_matrix(1,|PX|,1,Ones)
mult_matrix (PMean, Ones, 'AB', PSub)
sub_matrix(P,PSub,PShift)create_matrix(3,|QX|,[QX,QY,QZ],Q)
mean_matrix(Q,'rows', QMean)
create_matrix (1, |QX|, 0, Ones)
mult_matrix (QMean, Ones, 'AB', QSub)
sub_matrix (Q, QSub, QShift)*得到步骤2里的W矩阵,这里是3维点,左右W是个3*3矩阵
create_matrix (3, 3, 0, W)
for Index := 0 to |PX|-1 by 1get_sub_matrix (PShift, 0, Index, 3, 1, PVec)get_sub_matrix (QShift, 0, Index, 3, 1, QVec)transpose_matrix_mod (QVec)mult_matrix (PVec, QVec, 'AB', PQ)add_matrix_mod (W, PQ)    
endfor*对W进行svd分解
svd_matrix (W, 'full', 'both', U, S, V)*计算R
transpose_matrix_mod(U)
mult_matrix (V, U, 'AB', R)*计算R的行列式是否为1
determinant_matrix (R, 'general', Value)
if (Value < 0)get_value_matrix (V, [0,1,2], [2,2,2], Value1)set_value_matrix (V, [0,1,2], [2,2,2], [-Value1[0],-Value1[1],-Value1[2]])mult_matrix (V, U, 'AB', R)
endif*计算t
mult_matrix (R, PMean, 'AB', RPMean)
sub_matrix(QMean,RPMean,t)*得到最后的变换矩阵3*4
create_matrix(3,4,0,HomMat3DID)
set_sub_matrix (HomMat3DID, R, 0, 0)
set_sub_matrix(HomMat3DID, t, 0, 3)
get_full_matrix (HomMat3DID, HomMat3D)

得到的变换矩阵为

[-0.65053, 0.436583, 0.621455, -0.0714635, 0.519911, 0.852471, -0.0546402, -0.095308, -0.553627, 0.287556, -0.781542, 0.890677]

三、证明过程

    证明过程内容有点多,晚点整理整理再写

参考文章

三维重建(4)之SVD求解三维变换矩阵Rt(旋转+平移)_svd分解求旋转平移矩阵_明月醉窗台的博客-CSDN博客

使用SVD来求解优化问题最优值 - 知乎


http://www.ppmy.cn/news/81836.html

相关文章

python异常处理名称整理

Python 异常处理 python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。BaseException所有异常的基类UnboundLocalError访问未初始化的本地变量SystemExit

RK3568平台开发系列讲解(驱动基础篇)RK平台IR的使用

🚀返回专栏总目录 文章目录 一、红外遥控配置二、内核驱动2.1 DTS 定义键值表2.2 内核用户码和IR键值的获取2.3 编译 IR 驱动进内核2.4 Android 键值映射三、IR 波形沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将对RK IR的使用进行学习。 一、红外遥控配置 …

新的开始(最小生成树+超级源点)

题目 我们建立一个超级源点&#xff0c;每个点都与超级源点相连&#xff0c;他们的权值为在该点建立发电站的费用&#xff0c;剩下的将其余点相连&#xff0c;权值为连接到已经通电的发电站费用&#xff0c;我们跑一遍最小生成树即可将他们全部相连&#xff0c;并且费用最小。 …

算法时间复杂度

参考视频&#xff1a;https://www.bilibili.com/video/BV14j411f7DJ 目录 1.常数阶O(1) 2.对数阶O(IogN) 3.线性阶O(n) 4.线性对数阶O(nlogN) 5.平方阶O(n^2) 6.立方阶O(n^3) 7.K次方阶O(n^k) 8.指数阶(2^n) 9.阶乘O(n!) 两层for循环 for (int i 1; i <…

uniapp在H5获取当前定位信息不需要SDK可直接获取城市(包括经纬度省市区和市区编码)

前言 最近在做获取用户当前定位信息的时候&#xff0c;发现uniapp官方提供的uni.getLocation(OBJECT)兼容性并不是特别好&#xff0c;光注意事项都是密密麻麻一大堆&#xff0c;在实际使用场景下&#xff0c;效果并不理想&#xff0c;也不是很稳定。于是便重新封装了一下腾讯地…

MyBatis环境搭建+第一个MyBatis程序

目录 1.MyBatis是什么&#xff1f; 2.MyBatis开发环境搭建 3.我的第一个MyBatis程序 1.MyBatis是什么&#xff1f; MyBatis是一款数据库框架&#xff0c;是一款优秀的持久层框架&#xff0c;它不仅支持用户自定义SQL和存储过程&#xff0c;而且还具有高级映射功能。简单来说…

solr快速上手:核心概念及solr-admin界面介绍(二)

0. 引言 上一节&#xff0c;我们简单介绍了solr并演示了单节点solr的安装流程&#xff0c;本章&#xff0c;我们继续讲解solr的核心概念 solr快速上手&#xff1a;solr简介及安装&#xff08;一&#xff09; 1. 核心概念 核心&#xff08;索引/表&#xff09; 在es中有索引…

2.2.2 部署Master节点、添加Node节点

2.2.2 部署Master节点 1.安装docker、kubeadm、kubelet、kubectl 前面我们已经完成了虚拟机中系统的初始化&#xff0c;下面我们就在我们所有的节点上安装docker、kubeadm、kubelet、kubectl。 Kubernetes默认CRI&#xff08;容器运行时&#xff09;为Docker&#xff0c;因此…