最小二乘法实现二维多传感器标定
来源:互联网 发布:cnki数据库 编辑:程序博客网 时间:2024/06/14 11:25
最近用C++实现了多传感器的标定,实现方法很简单,但是很实用,特来分享一波。
二维多传感器标定问题
简单说明现在需要解决的问题。如图每个坐标系都代表一个传感器的位姿,十字星代表同一时刻两个传感器感知到的环境中的固定点(特征点)。现在已知两个传感器坐标系中个特征点的对应坐标值(带有噪声),需要求得两个传感器间的位姿变换参数(也就是这里的旋转矩阵R和平移矩阵T)。
数学表达如下
已知传感器a观测到的特征点(1,2,3…N)坐标(x,y)为:
已知传感器b观测到的特征点(1,2,3…N)坐标(w,z)为:
求xy坐标系变换到wz坐标系的平移参数与旋转参数。
坐标系变换可以表示为:
其中
利用Eigen库求解最小二乘解
为了在C++里实现带有矩阵运算的最小二乘法,我使用了Eigen库。Eigen是开源库,可以在主页下载:
(将Eigen文件夹放在源文件夹下即可)
http://eigen.tuxfamily.org/index.php?title=Main_Page
Eigen有给出很多最小二乘的解决方案,例如下面就有一个利用SVD做最小二乘的方法:
http://eigen.tuxfamily.org/dox/classEigen_1_1JacobiSVD.html
补全代码,可以得到一个可运行的例子:
#include <iostream>#include "Eigen/SVD"using namespace std;using namespace Eigen;int main(){MatrixXf m = MatrixXf::Random(3,2);cout << "Here is the matrix m:" << endl << m << endl;JacobiSVD<MatrixXf> svd(m, ComputeThinU | ComputeThinV);cout << "Its singular values are:" << endl << svd.singularValues() << endl;cout << "Its left singular vectors are the columns of the thin U matrix:" << endl << svd.matrixU() << endl;cout << "Its right singular vectors are the columns of the thin V matrix:" << endl << svd.matrixV() << endl;Vector3f rhs(1, 0, 0);cout << "Now consider this rhs vector:" << endl << rhs << endl;cout << "A least-squares solution of m*x = rhs is:" << endl << svd.solve(rhs) << endl;return 0;}
简单介绍上面代码。这个例子实现的是:
已知Mx=rhs,已知3* 2的矩阵M,以及3* 1的向量rhs。代码通过最小二乘法求得了最优的x。
步骤大致如下:
- 先利用
MatrixXf m = MatrixXf::Random(3,2);
生成了3*2的随机数矩阵m; 对m做SVD分解。这个JacobiSVD默认只会计算singular values。如果需要求得U或者V矩阵,需要另外设定。这里我们要求解最小二乘,只需要求解 thin U 和 thin V,所以用到的函数是:
JacobiSVD<MatrixXf> svd(m, ComputeThinU | ComputeThinV);
用svd.solve(rhs)求解x。
解决二维多传感器标定问题
前面的例程解出了
其中已知的是右边两个矩阵。所以我们需要先重构矩阵为:
现在就变成了Mx=rhs求解x的形式,可以简单改写例程即可求解:
#include <iostream>#include "Eigen/SVD"using namespace std;using namespace Eigen;int main(){MatrixXf m(6,4);m << 1.97,-2.03,1.1,0, 2,2.21,0,1, 3,-3,1,0, 3,3.1,0,1, 4,-3,1,0, 3,4,0,1;//m(0,0)= 2;m(0,1)=-2;m(0,2)=1;m(0,3)=0;//m(1,0)= 2;m(1,1)=2;m(1,2)=0;m(1,3)=1;//m(2,0)= 3;m(2,1)=-3;m(2,2)=1;m(2,3)=0;//m(3,0)= 3;m(3,1)=-3;m(3,2)=0;m(3,3)=1;//m(4,0)= 4;m(4,1)=-3;m(4,2)=1;m(4,3)=0;//m(5,0)= 3;m(5,1)=4;m(5,2)=0;m(5,3)=1;cout << "Here is the matrix m:" << endl << m << endl;JacobiSVD<MatrixXf> svd(m, ComputeThinU | ComputeThinV);cout << "Its singular values are:" << endl << svd.singularValues() << endl;cout << "Its left singular vectors are the columns of the thin U matrix:" << endl << svd.matrixU() << endl;cout << "Its right singular vectors are the columns of the thin V matrix:" << endl << svd.matrixV() << endl;VectorXf rhs(6);rhs << 2, 2, 3.02,3,4.11,3;cout << "Now consider this rhs vector:" << endl << rhs << endl;cout << "A least-squares solution of m*x = rhs is:" << endl << svd.solve(rhs) << endl;return 0;}
上面代码输入了带有噪声的三对点进行测试,运行结果与理论值近似。
在实际运用中,如果有P对点,需要将MatrixXf m(6,4);修改为MatrixXf m(P,4);。VectorXf rhs(6);修改为VectorXf rhs(P);。
输入矩阵有两种形式,一种是一次性输入,m << 1.97, … , …… ;
另一种是单个输入: m(0,0)= 2;m(0,1)=-2;m(0,2)=1;m(0,3)=0; …
根据输入需求进行修改即可。
参考
数组重构
https://math.stackexchange.com/questions/77462/finding-transformation-matrix-between-two-2d-coordinate-frames-pixel-plane-to
Eigen下载
http://eigen.tuxfamily.org/index.php?title=Main_Page
Eigen—JacobiSVD详解
http://eigen.tuxfamily.org/dox/classEigen_1_1JacobiSVD.html
- 最小二乘法实现二维多传感器标定
- 线结构光传感器标定
- 激光二维扫描传感器
- MC-20加速度传感器灵敏度标定仪
- 线结构光传感器的标定
- 气体传感器的量程标定方法
- 最小二乘法实现直线拟合
- 最小二乘法及其c++实现
- java 实现最小二乘法
- 最小二乘法实现数据拟合
- 最小二乘法编程实现方法
- 最小二乘法及C++实现
- 最小二乘法及其python实现
- 最小二乘法的实现
- 最小二乘法Java实现
- 最小二乘法的实现
- Python实现最小二乘法
- 最小二乘法及其C++实现
- java.lang.NoClassDefFoundError:com/sun/tools/javac/code/TypeTags
- 每日学习流水账
- jsp笔记
- 基于等价类的邮箱注册测试用例设计
- CSS@media查询
- 最小二乘法实现二维多传感器标定
- linux下安装scrpay框架
- Ignatius's puzzle HDU
- C#的值类型和引用类型解析
- Qt 学习之路 2(54):剪贴板
- Java多线程之原子性 volatile、atomicInteger、synchronized测试
- 10.1 信息论概述
- TX2运行ImageNet
- 分享一个自己写的简单的自动轮播的的函数