【计算机视觉】直接线性变换(DLT)求解P矩阵(2 使用SVD分解)(附MATLAB代码)

引言

之前的帖子已经完成了一种计算直接线性变换的方法,是直接通过矩阵运算来进行的,不过随后得到的结果并不能满足精度要求,如果只是用来作为迭代优化的一个初值的话,对于精度的要求倒也不用那么高。但在查阅资料时又发现了另一种解法,是通过SVD分解来进行的,确实可以得到精度更高的结果。

SVD分解

解释奇异值分解的原理的帖子也有很多,我就不班门弄斧了(主要是我也没怎么弄懂QAQ)
这里贴两个链接:
SVD(奇异值分解)小结
B站上一个讲奇异值分解的视频,这个强烈推荐:
什么是奇异值分解SVD

原理部分,感兴趣的可以自己去了解,这里只说明在DLT变换中如何使用。
通过对一个矩阵C进行奇异值分解可以得到U、S、V三个矩阵,其中S是一个由奇异值组成的对角阵。这里我们只需要用到S和V。

在上一篇帖子中,构造的等式是 CL = I ,然后通过矩阵运算解出L。

C矩阵的大小是 12×11,在改变方法过后,我们这里将右边的 I 移项到左边,在 L的末尾加上一个 1 ,将 I 项 与 C 项合并。
合并后的C矩阵的大小为 12×12。

然后对 C 矩阵进行奇异值分解,得到 U、S、V 三个矩阵(在MATLAB和EIGEN中使用SVD分解,得到的结果中的 V 实际都是V的转置,也就是Vt,但我们这里使用的就是Vt,至于为什么不直接写成Vt,因为我看到的资料里都是这样写的>_<)。

S 是一个由奇异值组成的对角阵,其中最小的奇异值所在的,在矩阵V(就是实际的Vt)中对应的列向量就是我们需要的结果了。
注:MATLAB和EIGEN中使用SVD分解得到的奇异值都是按照从大到小的顺序排列的,最小的奇异值就是最后列,因此这里我们直接取V的最后一列。如果是自己写SVD分解的话需要注意这一点。

废话就这么多了,直接看代码吧

MATLAB代码

%% DLT 算法需要用到 6 对点 ,前三列是 X Y Z 表示空间坐标 ,后两列 x y 表示图像坐标,下面是测试数据
Points = [  99.1517085791261, -0.892099762666786, 3.06159510601795, 163.209290388816, 182.199675950568;
		100.558334460204, 0.868021368458366, 2.25981241694746, 608.892566967667, 701.375883991155;
		100.137647321744, -0.0612187178835884, 2.02380413900248, 449.262241640596, 377.206100107244;
		99.6742452887978, -0.675635383613515, 3.58856908136781, 316.188427147902, 257.277246206713;
		99.6224300840896, 0.0570662710124255, 2.33129745899956, 267.575494465364, 430.054554508315;
		100.203963882803, -0.474057430919711, 3.30815819695356, 439.688462560083, 287.229433675101];

% 赋值 有6 个点,所以C的大小为 12×12,
C = zeros(12,12);
for i = 1:6
    X = Points(i,1);Y = Points(i,2);Z = Points(i,3);x = Points(i,4);y = Points(i,5);
    C(i*2-1,:) = [X,Y,Z,1,0,0,0,0,-x*X,-x*Y,-x*Z,-x];
    C(i*2,:)   = [0,0,0,0,X,Y,Z,1,-y*X,-y*Y,-y*Z,-y];
    
end

[U,S,V] = svd(C);

% 最小的奇异值对应的列向量
L = V(:,end);

P = reshape(L,[4,3])';
P = P/P(3,3);

%% 验证
Point3d = ones(4,6);
Point3d(1:3,:) = Points(:,1:3)';

Point2d = Points(:,4:5)';

Res = P*Point3d;

Res2d(1,:) = Res(1,:)./Res(3,:);
Res2d(2,:) = Res(2,:)./Res(3,:);

disp(Point2d)
disp(Res2d)

diff = Point2d - Res2d;
disp(diff);

运行结果

在这里插入图片描述

结语

可以看出,相较于上一篇帖子,改用SVD分解得到的结果精度是大幅度提高的。
本来是可以到此结束的,不过。。。那就再水一篇帖子吧!

【计算机视觉】直接线性变换(DLT)求解P矩阵(3 加入坐标的归一化)(附MATLAB代码

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值