首页 > 编程语言 >matlab练习程序(DLT)

matlab练习程序(DLT)

时间:2023-12-02 14:24:02浏览次数:42  
标签:cos uv xyz 练习 Tr matlab DLT 位姿 sin

在计算位姿的时候,一般我们有一些观测量,这些观测量有些是三维的、有些是二维的,因此需要用到不同的方法。

如果是3D-3D的位姿计算,一般可以用这几种方法(【1】,【2】,【3】,【4】)。

如果是3D-2D的位姿计算,一般可以用PnP-BA或者是本篇的DLT(直接线性变换)方法。

如果是2D-2D的位姿计算,一般可以用对极几何的方法,不过算不出尺度。

三维点投影到归一化二维平面可以用下面公式表示:

其中uv是二维归一化平面点,XYZ是三维投影点。

整理后可得AX=0这种形式,X就是公式中的12个l,A矩阵形式如下:

对于AX=0这种问题,一般都是对A奇异值分解或者对A'A特征值分解,然后拿其最小特征值对应的特征向量,作为该问题的解。

matlab代码如下:

clear all;close all;clc;

p = [rand(100,3)*100 ones(100,1)]';

i=1.2*pi/180.0;
j=88*pi/180.0;
k=-5.1*pi/180.0;
Rx=[1 0 0;0 cos(i) -sin(i); 0 sin(i) cos(i)];
Ry=[cos(j) 0 sin(j);0 1 0;-sin(j) 0 cos(j)];
Rz=[cos(k) -sin(k) 0;sin(k) cos(k) 0;0 0 1];
R=Rz*Ry*Rx;
T = [200;40;50];

srcR = [R T;0 0 0 1]

newp = inv(srcR)*p;
uv =[newp(1,:)./newp(3,:); newp(2,:)./newp(3,:)];

xyz = p(1:3,:)';

[newR, err] = DLTcalib(xyz, uv')

function [Tr, x] = Normalization(nd, x)

[m, s] = deal(mean(x, 1), std(x));

if nd == 2
Tr = [s(1), 0, m(1);
0, s(2), m(2);
0, 0, 1];
else
Tr = [s(1), 0, 0, m(1);
0, s(2), 0, m(2);
0, 0, s(3), m(3);
0, 0, 0, 1];
end

Tr = inv(Tr);
x = (Tr * [x'; ones(1, size(x, 1))]).';
x = x(:, 1:nd);

end

function [H, err] = DLTcalib(xyz, uv)
n = size(xyz, 1);

[Txyz, xyzn] = Normalization(3, xyz);
[Tuv, uvn] = Normalization(2, uv);

A = zeros(2*n, 12);

for i = 1:n
x = xyzn(i, 1);
y = xyzn(i, 2);
z = xyzn(i, 3);
u = uvn(i, 1);
v = uvn(i, 2);
A(2*i-1, :) = [x, y, z, 1, 0, 0, 0, 0, -u*x, -u*y, -u*z, -u];
A(2*i, :) = [0, 0, 0, 0, x, y, z, 1, -v*x, -v*y, -v*z, -v];
end

[~, ~, V] = svd(A);

% Camera projection matrix
H = reshape(V(:,end), [4, 3])';

% Denormalization
H = pinv(Tuv) * H * Txyz;

H = inv([H;0 0 0 1]);
H(1:3,1:3) = H(1:3,1:3)./norm(H(1:3,1:3));

uv2 = (inv(H) * [xyz'; ones(1, n)])';
uv2 = uv2(:, 1:2) ./ uv2(:, 3);

% Mean distance:
err = sqrt(mean(sum((uv2 - uv).^2, 2)));

end

可以看出计算得到的位姿和最初设置的位姿是一样的。

不过该方法计算时没有考虑旋转矩阵的约束,即A'A=I这种条件,因此计算的到的旋转量可能会有问题。

PnP-BA这种方法是不存在这种问题的。

标签:cos,uv,xyz,练习,Tr,matlab,DLT,位姿,sin
From: https://www.cnblogs.com/tiandsp/p/17854234.html

相关文章

  • java练习:json字符串转map、arrayList
    使用依赖包:<dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.0</version></dependency>获取数据:packagecom.example......
  • MATLAB时间序列数据重建与平滑:HANTS滤波
      本文介绍在MATLAB中,实现基于HANTS算法(时间序列谐波分析法)的长时间序列数据去噪、重建、填补的详细方法。  HANTS(HarmonicAnalysisofTimeSeries)是一种用于时间序列分析和插值的算法。它基于谐波分析原理,可以从观测数据中提取出周期性变化的信号成分,并进行数据插值和去噪......
  • PTA|C语言|数组练习题
    --------------------------------------------------------------------------------求最大值及其下标本题要求编写程序,找出给定的n个数中的最大值及其对应的最小下标(下标从0开始)。输入格式:输入在第一行中给出一个正整数n(1<n≤10)。第二行输入n个整数,用空格分开。输出格式:在一行......
  • matlab中绘制三维柱状图bar3函数的使用方法
    ✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。......
  • RGB转YCbCr——基于《基于MATLAB与FPGA的图像处理教程》
    YCbCr介绍YCbCr由Y、Cb、Cr组成。为一种数字信号1、Y:表示颜色的明亮度和浓度,也可叫灰度阶。(通过RGB转换YCBCR提取Y分量也可以得到灰度图像)2、Cb:表示颜色的蓝色浓度偏移量即RGB输入信号蓝色部分与RGB信号亮度值之间的差异。3、Cr:表示颜色的红色浓度偏移量即RGB输入信号红色部分......
  • matlab获取时间日期
    ​ 在MATLAB中得到系统当前日期、时间也是经常用到的内容,由以下函数实现。1.生成指定格式日期和时间datestr-生成指定格式日期和时间,是字符型变量。>> datestr(now) %其中now是获取当前日期和时间ans=    30-Dec-200916:05:16其中输出格式可由用户指定,共有31种......
  • Opencv实例练习
     实例所用的函数可在另一篇文章查询:  https://www.cnblogs.com/Zhouce/p/17867164.html1、图像读取1importcv2#引入opencv库2importnumpyasnp#引入numpy库3fn="car.png"45#img_color=cv2.imread(fn,1)#上下......
  • MATLAB图像分析程序
    ​1.迭代法 I=imread('rice.png');ZMax=max(max(I));ZMin=min(min(I));TK=(ZMax+ZMin)/2;bCal=1;iSize=size(I);while(bCal)iForeground=0;iBackground=0;ForegroundSum=0;BackgroundSum=0;fori=1:iSize(1)forj=1:iSize(2)tmp=I(i,j);if(tmp>=TK......
  • Matlab获取鼠标坐标值的ginput()函数
    ​获取鼠标坐标值的第一种途径:利用Matlab7.0中figure的WindowButtonDownFcn属性。当你在图上按下鼠标的时候,可通过该属性定义一个回调程序。回调程序可以是一个有效的Matlab表达式或者一个M文件。那么为显示当前鼠标按下时的坐标值,我们可以将其定义为一个坐标获取和显示程序。......
  • MATLAB实现图像小波变换去噪
    clear;[A,map]=imread('C:\Users\wangd\Documents\MATLAB\1.jpg');X=rgb2gray(A);%画出原始图像subplot(2,2,1);imshow(X);title('原始图像');%产生含噪图像x=imnoise(X,'gaussian',0,0.003);%画出含噪图像......