VIO第6讲:投影模型与三角化

VIO第6讲:投影模型与三角化

文章目录

3 三角化

  在三角化之前,复习一遍视觉投影模型与坐标变换,这对于求雅可比和三角化都是非常重要的。

3.1 坐标变换与投影模型

① 世界系->相机系 X w Y w Z w > > X c Y c Z c X_wY_wZ_w>>X_cY_cZ_c XwYwZw>>XcYcZc

在这里插入图片描述

  已知某点P在世界坐标系中的坐标 P w = ( X w , Y w , Z w ) T P_{w}=(X_{w},Y_{w},Z_{w})^{T} Pw=(Xw,Yw,Zw)T, 求其在相机坐标系中的坐标 P c = ( X c , Y c , Z c ) T P_c=(X_c,Y_c,Z_c)^T Pc=(Xc,Yc,Zc)T.

第一种方式Pc = Rcw*Pw + tcw

[ X c Y c Z c ] = R c w ⋅ [ X w Y w Z w ] + t c w \begin{bmatrix}Xc\\Yc\\Zc\end{bmatrix}=R_{cw}\cdot\begin{bmatrix}Xw\\Yw\\Zw\end{bmatrix}+t_{cw} XcYcZc =Rcw XwYwZw +tcw

  合并为齐次矩阵(投影矩阵)表达如下
[ X c Y c Z c 1 ] = [ R c w t c w → O 1 ] ⋅ [ X w Y w Z w 1 ] \begin{bmatrix}Xc\\Yc\\Zc\\1\end{bmatrix}=\begin{bmatrix}R_{cw}&t_{cw}\\\rightarrow\\O&1\end{bmatrix}\cdot\begin{bmatrix}Xw\\Yw\\Zw\\1\end{bmatrix} XcYcZc1 = RcwOtcw1 XwYwZw1
在这里插入图片描述

第二种方式Pc = Rcw*(Pw - twc) = Rcw*Pw - Rcw*twc

实际中使用第一种方式中的投影矩阵(3*4),其中的tcw往往由第二种方式推出tcw = -Rcw*twc

相机系坐标除以深度Z后,就是归一化坐标

② 相机->图像 X c Y c Z c > > x y X_cY_cZ_c>>xy XcYcZc>>xy

  实际上图像系坐标归一化坐标差一个焦距f的缩放!

在这里插入图片描述

  引入图像坐标系,即先求出相机坐标系下的点 P c = ( X c , Y c , Z c ) T P_c=(X_c,Y_c,Z_c)^T Pc=(Xc,Yc,Zc)T在图像坐标系下的表达 p ( x , y ) p(x,y) p(x,y)。利用相似三角形以及比例的原理,有以下推导及公式:
x f = X c Z c y f = Y c Z c \begin{aligned}\frac xf&=\frac{X_c}{Z_c}\\\frac yf&=\frac{Y_c}{Z_c}\end{aligned} fxfy=ZcXc=ZcYc
  所以,我们就能够推出上面结论:图像系坐标归一化坐标差一个焦距f的缩放
x = f X c Z c and y = f Y c Z c x=\frac{fX_c}{Z_c}\text{and}y=\frac{fY_c}{Z_c} x=ZcfXcandy=ZcfYc
  转换为矩阵乘法,其中 ( X c , Y c , Z c , 1 ) T (X_c,Y_c,Z_c,1)^T (Xc,Yc,Zc,1)T是空间点P在相机坐标系的齐次坐标, ( x , y , 1 ) T (x,y,1)^T (x,y,1)T是图像点p在图像坐标系中的齐次坐标。

Z c ⋅ [ x y 1 ] = [ f 0 0 0 0 f 0 0 0 0 1 0 ] ⋅ [ X c Y c Z c 1 ] Z_c\cdot\begin{bmatrix}x\\y\\1\end{bmatrix}=\begin{bmatrix}f&0&0&0\\0&f&0&0\\0&0&1&0\end{bmatrix}\cdot\begin{bmatrix}X_c\\Y_c\\Z_c\\1\end{bmatrix} Zc xy1 = f000f0001000 XcYcZc1

③ 图像->像素 x y > > u v xy>>uv xy>>uv

  设图像坐标系中心在像素坐标系的表达为 u 0 , v 0 u_0,v_0 u0,v0,图像上的投影点是 p ( x , y ) p(x,y) p(x,y)

在这里插入图片描述

   d x d_{x} dx像素宽度, d y d_{y} dy像素高度分别表示每个像素在水平u和竖直v方向上的实际物理尺寸(单位mm)。

u = x d x + u 0 v = y d y + v 0 \begin{aligned}u&=\frac x{dx}+u_0\\\\v&=\frac y{dy}+v_0\end{aligned} uv=dxx+u0=dyy+v0
   x d x \frac x{dx} dxx就表示在u方向占了多少像素,再加上中心坐标,就是实际的像素坐标。写成矩阵形式:

[ u v 1 ] = [ 1 d x o u 0 0 1 d y v 0 0 0 1 ] ⋅ [ x y 1 ] \begin{bmatrix}u\\v\\1\end{bmatrix}=\begin{bmatrix}\dfrac{1}{dx}&o&u_0\\0&\dfrac{1}{dy}&v_0\\0&0&1\end{bmatrix}\cdot\begin{bmatrix}x\\y\\1\end{bmatrix} uv1 = dx100ody10u0v01 xy1

④ 世界->像素

  把上面几个变换结合起来
Z c [ u v 1 ] = [ 1 d x o u 0 0 1 d y v 0 0 0 1 ] [ f 0 0 0 0 f 0 0 0 0 1 0 ] [ R t O → 1 ] [ X w Y w Z w 1 ] Z_c\begin{bmatrix}u\\v\\1\end{bmatrix}=\begin{bmatrix}\dfrac{1}{dx}&o&u_0\\0&\dfrac{1}{dy}&v_0\\0&0&1\end{bmatrix}\begin{bmatrix}f&0&0&0\\0&f&0&0\\0&0&1&0\end{bmatrix}\begin{bmatrix}R&t\\\overrightarrow{O}&1\end{bmatrix}\begin{bmatrix}Xw\\Yw\\Zw\\1\end{bmatrix} Zc uv1 = dx100ody10u0v01 f000f0001000 [RO t1] XwYwZw1
  合并左边两个矩阵,即常见的内参矩阵 K 3 ∗ 4 K_{3*4} K34外参矩阵 T 3 ∗ 4 T_{3*4} T34。其中, f x = f d x , f y = f d y f_x=\frac f{d_x},f_y=\frac f{d_y} fx=dxf,fy=dyf可以理解为焦距f分别在x,y轴方向等价的像素个数(每个像素的物理尺寸为dx×dy,单位为mm
Z c [ u v 1 ] = [ f x 0 u 0 0 0 f y v 0 0 0 0 1 0 ] [ R t O → 1 ] [ X w Y w Z w 1 ] Z_c\begin{bmatrix}u\\v\\1\end{bmatrix}=\begin{bmatrix}f_x&0&u_0&0\\0&f_y&v_0&0\\0&0&1&0\end{bmatrix}\begin{bmatrix}R&t\\\overrightarrow{O}&1\end{bmatrix}\begin{bmatrix}Xw\\Yw\\Zw\\1\end{bmatrix} Zc uv1 = fx000fy0u0v01000 [RO t1] XwYwZw1

⑤ 问题

问题:

已知一款相机佳能80D及镜头参数如下:最高分辨率6000×4000,传感器尺寸22.3×14.9mm,焦距f=35mm,根据相机内参定义,估算相机的内参fx,fy,u0,v0

答案:

fx = f / dx = 35 / (22.3/6000) = 9417.040358744
fy = f / dy = 35 / (14.9/4000) = 9395.973154362
u0= 6000 / 2 = 3000
v0= 4000 / 2 = 2000

由于制造工艺等因素,相机像素坐标系中心未必与光轴经过的图像坐标系中心重合,即(u0,v0)并非是像素坐标系的中心,而是在中心附近某个位置,焦距及像素物理尺寸也非绝对精准,故而需要通过实际的内参标定过程,确定相机的内参矩阵。

参考链接

3.2 单目三角化

3.2.1 三角化推导

  某路标点L在若干个关键帧 k = 1,··· ,n 中看到,取齐次坐标 y ∈ R 4 \mathbf{y}\in\mathbb{R}^4 yR4,观测取归一化坐标 ( x , y , 1 ) (x,y,1) (x,y,1),这样可以忽略相机内参,只利用相机系和世界系坐标。
λ [ x y 1 ] = [ R c w t c w ] ⋅ [ X w Y w Z w 1 ] λ\begin{bmatrix}x\\y\\1\end{bmatrix}=\begin{bmatrix}R_{cw}&t_{cw}\\\end{bmatrix}\cdot\begin{bmatrix}Xw\\Yw\\Zw\\1\end{bmatrix} λ xy1 =[Rcwtcw] XwYwZw1
  利用投影矩阵P第三行就能代入矩阵上面两行,即一个特征点通过投影矩阵P可以提供两个约束方程!

  对于n个匹配特征点, D ∈ R 2 n × 4 \mathbf{D}\in\mathbb{R}^{2n\times4} DR2n×4
[ x 1 P 1 , 3 ⊤ − P 1 , 1 ⊤ y 1 P 1 , 3 ⊤ − P 1 , 2 ⊤ ⋮ x n P n , 3 ⊤ − P n , 1 ⊤ y n P n , 3 ⊤ − P n , 2 ⊤ ] [ X w Y w Z w 1 ] = 0 → D L = 0 \left.\left[\begin{array}{c}x_1\mathbf{P}_{1,3}^\top-\mathbf{P}_{1,1}^\top\\y_1\mathbf{P}_{1,3}^\top-\mathbf{P}_{1,2}^\top\\\vdots\\x_n\mathbf{P}_{n,3}^\top-\mathbf{P}_{n,1}^\top\\y_n\mathbf{P}_{n,3}^\top-\mathbf{P}_{n,2}^\top\end{array}\right.\right]\begin{bmatrix}Xw\\Yw\\Zw\\1\end{bmatrix}=\mathbf{0}\to\mathbf{D}\mathbf{L}=\mathbf{0} x1P1,3P1,1y1P1,3P1,2xnPn,3Pn,1ynPn,3Pn,2 XwYwZw1 =0DL=0

三角化数学推导具体推导参考链接,同ORB-SLAM。构建矩阵D的代码如下

int D_dim_row = 2 * (end_frame_id - start_frame_id);int D_dim_col = 4;Eigen::MatrixXd D = Eigen::MatrixXd::Zero(D_dim_row, D_dim_col);// 每一个特征点可以提供两行约束for(int i = start_frame_id; i < end_frame_id; i++){Eigen::MatrixXd P = Eigen::MatrixXd::Zero(3, 4);// 构建投影矩阵//  P.block<3,3>(0,0) = camera_pose[i].Rwc.transpose();P.block(0, 0, 3, 3) = camera_pose[i].Rwc.transpose();   // RcwP.block(0, 3, 3, 1) = -camera_pose[i].Rwc.transpose() * camera_pose[i].twc;     // tcw// 归一化坐标点(u,v,1)----当前帧-----在Eigen库中,可以使用( )操作符或者[ ]操作符---或uv.x() uv.ydouble x = camera_pose[i].uv[0];double y = camera_pose[i].uv[1];// 代入公式----每一个特征点可以提供两行约束D.block(2 * (i - start_frame_id), 0, 1 , 4) = x * P.row(2) - P.row(0);  D.block(2 * (i - start_frame_id) + 1, 0, 1 , 4) = y * P.row(2) - P.row(1);}

3.2.2 三角化求解

  在观测次于大于等于两次时,很可能 D 满秩,无零空间,这样就只有0解,但这是不对的。所以,寻求最小二乘解来替代:
min ⁡ y ∥ D L ∥ 2 2 , \min_\mathbf{y}\left\|\mathbf{DL}\right\|_2^2, yminDL22,
  然后,利用SVD分解进行求解(关于SVD,可以参考博客,这里就是要知道SVD分解中的D和V都是可以由被分解矩阵与其转置的乘积的特征向量组成,所以下面最小奇异值对应最小特征向量!在第4部分给出代码测试,还有不要和下面的D混淆)
D ⊤ D = ∑ i = 1 4 σ i 2 u i u j ⊤ \mathbf{D}^\top\mathbf{D}=\sum_{i=1}^4\sigma_i^2\mathbf{u}_i\mathbf{u}_j^\top DD=i=14σi2uiuj
  最后,右奇异矩阵的最后一列就是最终的解。至于原有,曾经在ORB-SLAM2中推导过
在这里插入图片描述

还看到一个利用拉格朗日算子推理的

在这里插入图片描述

代码实现

    Eigen::JacobiSVD<Eigen::MatrixXd> svd(D.transpose()*D, Eigen::ComputeThinU | Eigen::ComputeThinV);// 调用svd对象的singularValues()成员函数,矩阵D的奇异值Eigen::Vector4d delta = svd.singularValues();// 取最小奇异值对应的右奇异向量----注意上面是对D^T*D进行了SVD分解,相当于对一个对称矩阵进行特征分解,两边UV都是一样的,所以这里取U也可以。但如果是对D进行SVD分解,只能是取V!Eigen::Vector4d u4 = svd.matrixU().col(3);

3.2.3 求解注意点

① 判断该解有效性的条件 σ 4 ≪ σ 3 \sigma_{4}\ll\sigma_{3} σ4σ3
    if(delta(3) * 1e-3 > delta(2)){   // 一般来讲奇异值都是从小到大,只要视差合理,这种极端情况不会出现std::cout << "The parallax is not enough" << std::endl;return -1;}
σ 4 ! = 0 \sigma_{4}!= 0 σ4=0 且深度>0
    if(u4(3) != 0 && u4(2) / u4(3) > 0){P_est = u4.head<3>() / u4(3);}
③ Rescale

  在某此场合(比如我们使用 UTM 坐标的平移),D 的数值大小差异明显,导致解在数值上不稳定。此时对 D 做一个缩放
D y = D S ⏟ D ~ S − 1 y ⏟ y ~ = 0 \mathrm{Dy=\underbrace{DS}_{\tilde{D}}\underbrace{S^{-1}y}_{\tilde{y}}=0} Dy=D~ DSy~ S1y=0
  其中 S 为一个对角阵,取 D 最大元素之逆即可。

3.2.4 测量值噪声

  这里仿真的位姿以及地图点都是没有误差的,实际中路标点投影到相机帧中不可能是没有误差的,所以这里可以加一个测量噪声,来验证算法的有效性!

double x = Pc.x();
double y = Pc.y();
double z = Pc.z();double x_noise = x/z + noise(generator);
double y_noise = y/z + noise(generator);// camera_pose[i].uv = Eigen::Vector2d(x/z,y/z);
camera_pose[i].uv = Eigen::Vector2d(x_noise,y_noise);

3.2.5 特征点数量对结果的影响

  固定噪声方差参数,将观测图像帧扩成多帧(如3, 4 ,5,6,7,8等),观察最小奇异值和第二小奇异值之间的比例变化,并绘制比例值的变化曲线。

  这个就更简单了,把那个end_frame_id改了。

4 SVD分解

A = D*S*V^T,例子来源维基百科

验证了A^T*A的特征向量组成了A奇异值分解中的矩阵V

同理A*A^T的特征向量组成了A奇异值分解中的矩阵U

代码,其余理论可参考博客

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/494326.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型推理加速技术:模型压缩篇

原文&#xff1a;大语言模型推理加速技术&#xff1a;模型压缩篇 - 知乎 目录 简介 量化(Quantization) LLM.int8() GPTQ SmoothQuant AWQ 精简Attention 共享Attention参数 Multi-Query Attention Grouped-Query Attention 稀疏Attention Sliding Window Attenti…

Maple Trees Package

此软件包包含8棵完全可编辑的枫树&#xff0c;可立即使用&#xff1a;碰撞已经设置好&#xff0c;在任何树层的每个级别上仔细调整弯曲&#xff0c;纹理将与设置一起导入&#xff0c;为您提供最佳外观。 探索树木&#xff01; 规格 高度&#xff1a;6-20米 特里斯&#xff1a;当…

html中的meta 元信息

html中的meta 元信息 1. 配置字符编码 <meta charset"utf-8">2. 针对 IE 浏览器的兼容性配置。 <meta http-equiv"X-UA-Compatible" content"IEedge">3. 针对移动端的配置 <meta name"viewport" content"widt…

【论文阅读】Vison-Language Navigation 视觉语言导航(1)

ACL 2022 VLN视觉和语言导航&#xff1a;任务、方法和未来方向综述 多模态任务新蓝海&#xff1a;视觉语言导航最新进展 Leader board in VLN RXR&#xff1a; Room-across-Room (RxR) is a large-scale, multilingual dataset for Vision-and-Language Navigation (VLN) in…

SpringBoot快速入门(黑马学习笔记)

需求 需求&#xff1a;基于SpringBoot的方式开发一个Web应用&#xff0c;浏览器发起请求/hello后&#xff0c;给浏览器返回字符串"Hello World~"。 开发步骤 第一步&#xff1a;创建SpringBoot工程项目 第二步&#xff1a;定义HelloController类&#xff0c;添加方…

华为手动ipv6-to-ipv4隧道

中间r2的两个接口配置两个地址就行了&#xff0c;其它什么都不用配置 两边出接口R1和R3手动隧道建立&#xff1a;先把IPV4打通&#xff0c;并配置默认路由 再起隧道接口上进行配置&#xff0c;再配置带隧道的默认路由 PC上和上联接口网关只有IPV6地址 最终两个PC可以ping通 …

【Datawhale组队学习:Sora原理与技术实战】Sora技术原理

Sora能力边界探索 最大支持60秒高清视频生成&#xff0c;以及基于已有短视频的前后扩展&#xff0c;同时保持人物/场景的高度一致性如奶茶般丝滑过渡的视频融合能力同一场景的多角度/镜头的生成能力具有动态摄像机运动的视频。随着摄像机的移动和旋转&#xff0c;人和其 他场景…

Stable Diffusion 绘画入门教程(webui)-ControlNet(NormalMap)

法线贴图NormalMap可以把参考图的光影分布关系,法线贴图可以实现在不改变物体真实结构的基础上也能反映光影分布的效果&#xff0c;被广泛应用在 CG 动画渲染和游戏制作等领域 简单来讲可以参考原图的光影明暗关系并还原原图姿态&#xff0c;如下图&#xff1a;左边为原图&…

Java向ES库中插入数据报错:I/O reactor status: STOPPED

Java向ES库中插入数据报错&#xff1a;java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STO 一、问题问题原因 二、解决思路 一、问题 在使用Java向ES库中插入数据时&#xff0c;第一次成功插入&#xff0c;第二次出现以下错误&#xff1a…

StarRocks之监控管理(内含DashBoard模板)

先看下最终效果图 架构 Prometheus 是一个拥有多维度数据模型的、灵活的查询语句的时序数据库。它可以通过 Pull 或 Push 采集被监控系统的监控项,存入自身的时序数据库中。并且通过丰富的多维数据查询语言,满足用户的不同需求。 Grafana 是一个开源的 Metric 分析及可视化系…

RK3568平台开发系列讲解(基础篇)如何快速学习一套 Linux开发板源码

🚀返回专栏总目录 文章目录 一、基础代码二、驱动代码沉淀、分享、成长,让自己和他人都能有所收获!😄 拿到一份源码和一块评估板,如何快速找到与这块板相关的源码,是很多研发人员都曾遇到过的问题。如果对内核源码结构有大概了解,要完成这些事情也不难,通常可按照基础…

java:关于类的基础知识

一、类和对象 1.什么是类 类是对现实生活中一类具有共同属性和行为的事物的抽象。 2.类的特点&#xff1a; 类是对象的数据类型类是具有相同属性和行为的一组对象的集合 3.什么是对象的属性 属性&#xff1a;对象具有的各种特征&#xff0c;每个对象的每个属性都拥有特定…