相机光心在世界坐标系下的坐标(相机坐标系原点在世界坐标系下的坐标与c2w的关系)

本文详细介绍了相机坐标系与世界坐标系之间的转换关系,包括坐标变换矩阵和平移向量的概念。通过数学公式阐述了坐标变换的原理,并提供了获取相机坐标系原点在世界坐标系下坐标的代码示例。内容参考自《视觉SLAM14讲》第二版,强调了理解坐标变换对于解决实际问题的重要性。
摘要由CSDN通过智能技术生成

例子

如下图所示,右边的坐标系是相机坐标系,左边的是世界坐标系。
假设他们只有 x 轴方向上的平移。
相机坐标系原点在相机坐标系下的坐标是 (0,0,0),
假设相机坐标系在世界坐标系沿 x 轴正方向 5 m 外,
则在世界坐标系下,相机坐标系原点的坐标为 (5,0,0)
也就是说针对任意一点 P,它在相机坐标系下的坐标为 (x_c,y_c,z_c)
那么它在世界坐标系下的坐标为 (x_c+5,y_c,z_c)
此时 c2w(camera to world) 矩阵右上角的 平移向量 为 (5,0,0)
也就是说 平移向量跟相机坐标系原点在世界坐标系下的坐标是一样的
在这里插入图片描述

如何取得相机坐标系原点在世界坐标系下的坐标

原理

定义坐标系1、坐标系2,那么向量 a \mathbf{a} a 在两个坐标系下的坐标为 a 1 \mathbf{a}_1 a1, a 2 \mathbf{a}_2 a2,它们之间的关系应该是
a 1 = R 12 a 2 + t 12 \mathbf{a}_1 = \mathbf{R}_{12}\mathbf{a}_2+\mathbf{t}_{12} a1=R12a2+t12
这里的
R 12 \mathbf{R}_{12} R12
是指“把坐标系2的向量变换到坐标系1”中。由于向量乘在这个矩阵的右边,它的下标是从右读到左的。同理,如果我们要表达“从1到2的旋转矩阵”时,就写成
R 21 \mathbf{R}_{21} R21
关于平移
t 12 \mathbf{t}_{12} t12
它实际对应的是坐标系1原点指向坐标系2原点的向量,在坐标系1下取的坐标,所以建议读成“从1到2的向量”。
相反地,
t 21 \mathbf{t}_{21} t21
即从2指向1的向量在坐标系2下的坐标,却并不等于 − t 12 -\mathbf{t}_{12} t12,而是和两个坐标系的旋转还有关系。
所以,当初学者问“我的坐标在哪里”这样的问题时,我们需要清楚地说明这句话的含义。这里“我的坐标”实际上指的是从世界坐标系指向自己坐标系原点的向量,在世界坐标系下取到的坐标。对应到数学符号上,应该是
t W C \mathbf{t}_{WC} tWC 的取值。
同理,它并不等于
− t C W -\mathbf{t}_{CW} tCW

代码

ray_o = c2w[:3, 3] 

相机原点(光心)在世界坐标系下取到的坐标用上述代码获取。
首先 c 2 w c2w c2w 是 相机到 世界坐标系的变换矩阵,对应平移向量可以写成
t W C \mathbf{t}_{WC} tWC
注意
W ← C W\leftarrow C WC
自右向左

为什么

至于为什么是这样,举个例子就很清楚,因为是坐标系的变换,所以刚好和坐标的变换有点相反过来的味道。

参考

《视觉SLAM14讲》第二版,电子工业出版社,p45-p46

以下是基于 MATLAB 的标准粒子群算法求解无人机集群威胁重心在惯性坐标系下的坐标的源代码: ```matlab % 定义目标函数,即集群威胁重心与原点之间的欧几里得距离 function f = fitness(x) f = sqrt(x(1)^2 + x(2)^2); end % 初始化粒子群 function swarm = init_swarm(n, dim, lb, ub) swarm = struct; swarm.n = n; swarm.dim = dim; swarm.lb = lb; swarm.ub = ub; swarm.x = lb + (ub - lb) .* rand(n, dim); swarm.v = zeros(n, dim); swarm.pbest = swarm.x; swarm.gbest = swarm.x(randi(n), :); swarm.fpbest = arrayfun(@fitness, swarm.x); swarm.fgbest = fitness(swarm.gbest); end % 更新粒子群 function swarm = update_swarm(swarm, w, c1, c2) swarm.v = w * swarm.v ... + c1 * rand * (swarm.pbest - swarm.x) ... + c2 * rand * (swarm.gbest - swarm.x); swarm.x = swarm.x + swarm.v; % 限制粒子位置在边界内 swarm.x(swarm.x < swarm.lb) = swarm.lb(swarm.x < swarm.lb); swarm.x(swarm.x > swarm.ub) = swarm.ub(swarm.x > swarm.ub); % 更新历史最优位置和全局最优位置 fp = arrayfun(@fitness, swarm.x); swarm.pbest(fp < swarm.fpbest, :) = swarm.x(fp < swarm.fpbest, :); swarm.fpbest(fp < swarm.fpbest) = fp(fp < swarm.fpbest); [swarm.fgbest, gbest_idx] = min(swarm.fpbest); swarm.gbest = swarm.pbest(gbest_idx, :); end % 主函数 function main() % 参数设置 n = 50; % 粒子数 dim = 2; % 搜索维度 lb = [-10, -10]; % 搜索下界 ub = [10, 10]; % 搜索上界 max_iter = 100; % 最大迭代次数 w = 0.729; % 惯性权重 c1 = 1.49445; % 加速度常数1 c2 = 1.49445; % 加速度常数2 % 初始化粒子群 swarm = init_swarm(n, dim, lb, ub); % 迭代更新粒子群 for iter = 1:max_iter swarm = update_swarm(swarm, w, c1, c2); fprintf('iter = %d, fgbest = %f\n', iter, swarm.fgbest); end % 输出结果 fprintf('gbest = (%f, %f)\n', swarm.gbest(1), swarm.gbest(2)); end ``` 这段代码定义了目标函数、初始化粒子群、更新粒子群和主函数,并在主函数中进行了参数设置和迭代更新粒子群的操作。在迭代更新过程中,输出了当前迭代次数和全局最优值,方便观察算法收敛情况。最终输出了全局最优位置,即为集群威胁重心在惯性坐标系下的坐标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

培之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值