- 学习之前内容碰到的一些小demo,感觉很简单,所以没在自己环境下运行。等学完李群李代数(抽象数学,理论推导较多)后,已经出现了eigen库(矩阵计算)、pangolin库(一种可视化工具,类似于ros当中的rviz)、sophus库(eigen升级版,加入李群李代数的计算)等有意思的库,便想跑一跑相关的demo。
- 痛苦因此产生。笔者的linux系统是unbantu20.04.6(双系统),IDE用的是VScode。eigen库还好,虽然遇到了问题,但最终找到解决之法。可怕的是pangolin库,报错层出不穷,从改cmakelist.txt到安装不同版本的pangolin(eg: pangolin-0.5、pangolin-0.6、最新版),浪费了宝贵的一天(没进展且没relax),共阅30篇左右解决问题的博客,问题依旧存于人间。
- 但笔者never give up ,若找到解决之法(但愿),后期会专门出一篇 报错-解决方案大全。
视觉SLAM学习打卡【4】-相机和图像
一、相机在机器人里充当的角色
1.slam问题的数学表述
(1)运动方程
x k = f ( x k − 1 , u k , w k ) \mathrm x_\mathrm{k}=\mathrm f(\mathrm x_{k-1},\mathrm u_\mathrm{k},\mathrm w_\mathrm{k}) xk=f(xk−1,uk,wk)
- x k \mathrm x_\mathrm{k} xk、 x k − 1 \mathrm x_\mathrm{k-1} xk−1表示小萝卜在k和k − 1时刻的位置.
- u k \mathrm u_\mathrm{k} uk表示运动传感器的读数(有时也叫输入).
- w k \mathrm w_\mathrm{k} wk表示噪声.
(2)观测方程
z k , j = h ( y j , x k , v k , j ) \mathrm z_\mathrm{k,j}=\mathrm h(\mathrm y_\mathrm{j},\mathrm x_\mathrm{k},\mathrm v_\mathrm{k,j}) zk,j=h(yj,xk,vk,j)
- 表示小萝卜在 x k \mathrm x_\mathrm{k} xk位置上看到路标点 y j \mathrm y_\mathrm{j} yj产生的观测数据 z k , j \mathrm z_\mathrm{k,j} zk,j
- y j \mathrm y_\mathrm{j} yj表示第j个路标点
- v k , j v_\mathrm{k,j} vk,j表示噪声
2.观测数据即为相机的成像过程
在以相机为主的视觉SLAM中,观测方程的观测数据 z k , j \mathrm z_\mathrm{k,j} zk,j指相机的成像过程.
二、针孔相机模型
介绍此模型,共用到五种坐标:世界坐标、相机坐标、归一化坐标、成像坐标和像素坐标。为厘清它们之间的关系,做图如下:
- 空间点P在相机坐标系下的坐标为 [ X , Y , Z ] T [\mathrm{X},\mathrm{Y},\mathrm{Z}]^\mathrm{T} [X,Y,Z]T,投影到成像坐标系下的坐标为 [ X ′ , Y ′ , Z ′ ] T [\mathrm{X'},\mathrm{Y}^{\prime},\mathrm{Z'}]^{\mathrm{T}} [X′,Y′,Z′]T,由相似关系可得: Z f = − X X ′ = − Y Y ′ \frac{Z}{f}=-\frac{X}{X'}=-\frac{Y}{Y'} fZ=−X′X=−Y′Y
- 针孔模型投影为倒像,故有负号。实际相机中会通过软件自动翻转,此处可以把负号去掉。
Z f = X X ′ = Y Y ′ \frac{Z}{f}=\frac{X}{X'}=\frac{Y}{Y'} fZ=X′X=Y′Y整理得:
{ X’=f X Z Y’=f Y Z \left.\left\{\begin{aligned}&\text{X'=f}\frac{\text{X}}{\text{Z}}\\ &\text{Y'=f}\frac{\text{Y}}{\text{Z}}\end{aligned}\right.\right. ⎩ ⎨ ⎧X’=fZXY’=fZY - 像素坐标系和成像坐标系之间,相差一个缩放和原点的平移。转换得到的投影点P’在像素坐标系上的像素坐标为 P u , v \mathrm{P}_{\mathrm{u,v}} Pu,v
P u , v = [ u , v ] T \mathrm{P_{u,v}=[u,v]^{T}} Pu,v=[u,v]T { u = α X ′ + c x = f x X Z + c x v = β Y ′ + c y = f x X Z + c x \left.\left\{\begin{aligned}\mathrm{u=\alpha X'+c_x~=f_x\frac{X}{Z}~+c_x} \\\mathrm{v=\beta Y'+c_y~=f_x\frac{X}{Z}~+c_x}\end{aligned}\right.\right. ⎩ ⎨ ⎧u=αX′+cx =fxZX +cxv=βY′+cy =fxZX +cx其中 f x = α f f_x=\alpha f fx=αf, f y = β f f_y=\beta f fy=βf。 u , v , c x , c y , f x , f y \mathrm{u,v,c_x,c_y,f_x,f_y} u,v,cx,cy,fx,fy单位为像素, α \alpha α、 β \beta β的单位为像素/米。 - 把上式写成矩阵表达式 Z P u v = Z [ u v 1 ] = [ f x 0 c x 0 f y c y 0 0 1 ] [ X Y Z ] ≜ K P \left.\mathrm{ZP}_{\mathrm{uv}}=\mathrm{Z}\left[\begin{array}{c}\mathrm{u}\\\mathrm{v}\\1\end{array}\right.\right]=\left[\begin{array}{ccc}\mathrm{f}_\mathrm{x}&0&\mathrm{c}_\mathrm{x}\\0&\mathrm{f}_\mathrm{y}&\mathrm{c}_\mathrm{y}\\0&0&1\end{array}\right]\left[\begin{array}{c}\mathrm{X}\\\mathrm{Y}\\\mathrm{Z}\end{array}\right]\triangleq\mathrm{KP} ZPuv=Z
uv1
=
fx000fy0cxcy1
XYZ
≜KP
其中矩阵K称为相机的内参数矩阵. - 由于相机的位姿随着机器人运动不断变化,需要进行世界坐标到相机坐标的坐标变换。 Z P u v = K ( R P W + t ) = K T P W \mathrm{ZP}_\mathrm{uv}=\mathrm{K}(\mathrm{RP}_\mathrm{W}+\mathrm{t})=\mathrm{KTP}_\mathrm{W} ZPuv=K(RPW+t)=KTPW
- 将最后一维Z进行归一化处理,得到点P在归一化平面的归一化坐标 P c = [ X / Z , Y / Z , 1 ] T \mathrm{P_{c}=[X/Z,Y/Z,1]^{\mathrm{T}}} Pc=[X/Z,Y/Z,1]T
注:由 p u v = k T p w z p_{uv}=kT\frac{p_{w}}{z} puv=kTzpw可知,不管空间上有多少点 p w p_{w} pw(实际上为光心到归一化平面上一点射线包含的所有点),都用一个 p u v p_{uv} puv坐标表示,即点的深度在投影过程中被丢失了。
三、畸变模型
由于透镜的自身形状影响光线及机械组装不平行,导致成像出现几遍。
- 径向畸变(坐标点沿长度方向变化):分为桶形畸变和枕形畸变
x d i s t o r t e d = x ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) y d i s t o r t e d = y ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) \begin{array}{rl}\mathrm{x_{distorted}}&=\mathrm{x(1+k_1r^2+k_2r^4+k_3r6)}\\\mathrm{y_{distorted}}&=\mathrm{y(1+k_1r^2+k_2r^4+k_3r6)}\end{array} xdistortedydistorted=x(1+k1r2+k2r4+k3r6)=y(1+k1r2+k2r4+k3r6) - 切向畸变(坐标点沿水平夹角变化)
x d i s t o r t e d = x + 2 p 1 x y + p 2 ( r 2 + 2 x 2 ) y d i s t o r t e d = y + p 1 ( r 2 + 2 y 2 ) + 2 p 2 x y \begin{array}{l}\mathrm{x_{distorted}~=x+2p_1xy+p_2(r^2+2x^2)}\\\mathrm{y_{distorted}~=y+p_1(r^2+2y^2)+2p_2xy}\end{array} xdistorted =x+2p1xy+p2(r2+2x2)ydistorted =y+p1(r2+2y2)+2p2xy - 对归一化平面上的点计算径向畸变和切向畸变
{ x c o r r e c t e d = x ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) + 2 p 1 x y + p 2 ( r 2 + 2 x 2 ) y c o r r e c t e d = y ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) + p 1 ( r 2 + 2 y 2 ) + 2 p 2 x y . \left.\left\{\begin{aligned}x_{\mathrm{corrected}}&=x\left(1+k_1r^2+k_2r^4+k_3r^6\right)+2p_1xy+p_2\left(r^2+2x^2\right)\\y_{\mathrm{corrected}}&=y\left(1+k_1r^2+k_2r^4+k_3r^6\right)+p_1\left(r^2+2y^2\right)+2p_2xy\end{aligned}\right.\right.. { xcorrectedycorrected=x(1+k1r2+k2r4+k3r6)+2p1xy+p2(r2+2x2)=y(1+k1r2+k2r4+k3r6)+p1(r2+2y2)+2p2xy.
四、双目相机模型
由 Δ P P L P R 与 Δ P P O L O R \Delta PP_{L}P_{R}\text{与}\Delta PPO_{L}O_{R} ΔPPLPR与ΔPPOLOR相似得:
z − f z = b − u L + u R b \frac{z-f}z=\frac{b-u_L+u_R}b zz−f=bb−uL+uR整理得 z = f b d , d = d e f u L − u R z=\frac{fb}d,d\stackrel{def}=u_L-u_R z=dfb,d=defuL−uR
- d为视差。视察越大,距离越近.(由于视差最小为1像素,所以双目深度最大在理论上为fb)
- 基线b越大,双目测得得最大距离越远(依此分析面向,是不是眼间距越宽,看的越“长远”呢)
五、RGB-D相机模型
通过物理方式测距.
1.通过红外结构光原理测量像素距离
相机根据返回得结构光图案,计算物体与自身之间的距离。
2.通过飞行时间法 (Time-of- flight, ToF) 原理测量像素距离
相机向目标发射脉冲光,根据发送到返回之间的光束飞行时间,确定物体与自身的距离。
六、图像
计算机把图像(由多个像素组成)以矩阵的形式储存在内存中。
#表示一张宽度为640像素、高度为480像素分辨率的灰度图
unsigned char image[480][640];
#访问位于(x,y)处的像素
unsigned char pixel = image[y][x];