【视觉SLAM十四讲源码解读】坐标变换 像素坐标系、图像坐标系、相机坐标系、相机归一化坐标系、世界坐标系

什么是世界坐标系

世界坐标系是为了描述相机的位置而被引入的,平移向量T是第一个坐标原点与第二个坐标原点的偏移量;
世界坐标系(Ow,以空间一点为原点)

世界坐标系(world coordinate)(xw,yw,zw),也称为测量坐标系,是一个三维直角坐标系,以其为基准可以描述相机和待测物体的空间位置。世界坐标系的位置可以根据实际情况自由确定。

什么是相机坐标系

相机坐标系(Oc以小孔即光心为原点) (Xc,Yc,Zc)至图像坐标系(x,y)
根据小孔成像原理,图像坐标系应在相机坐标系的另一边,为倒立反向成像,但为方便理解和计算,故投影至同侧。

相机坐标系(camera coordinate)(xc,yc,zc),也是一个三维直角坐标系,原点位于镜头光心处,x、y轴分别与相面的两边平行,z轴为镜头光轴,与像平面垂直。
在这里插入图片描述

什么是图像物理坐标系

成像平面坐标系(x,y):像素坐标系不利于坐标变换,因此需要建立图像坐标系XOY,其坐标轴的单位通常为毫米(mm),原点是相机光轴与相面的交点(称为主点),即图像的中心点,X轴、Y轴分别与u轴、v轴平行。故两个坐标系实际是平移关系,即可以通过平移就可得到。
图像物理坐标系(O1以像平面中心为原点)

什么是像素坐标系

像素坐标系uov是一个二维直角坐标系,反映了相机CCD/CMOS芯片中像素的排列情况。原点o位于图像的左上角,u轴、v轴分别于像面的两边平行。像素坐标系中坐标轴的单位是像素(整数)。
图像像素坐标系(O以像平面左下角为原点)

像素坐标系和图像坐标系都在成像平面上,只是各自的原点和度量单位不一样。图像坐标系的原点为相机光轴与成像平面的交点,通常情况下是成像平面的中点或者叫principal point。图像坐标系的单位是mm,属于物理单位,而像素坐标系的单位是pixel,我们平常描述一个像素点都是几行几列。所以这二者之间的转换如下:其中dx和dy表示每一列和每一行分别代表多少mm,即1pixel=dx mm

重点就是u0和v0的值是在像素坐标系下的中心像素,比如600*400,那坐标就是(300,200)
所以才可以有下面的加法

伸缩变换及平移变换
在这里插入图片描述
四个坐标系之间存在着下述关系 ( 矩阵依次左乘 )
在这里插入图片描述
在这里插入图片描述
一个三维中的坐标点,的确可以在图像中找到一个对应的像素点,但是反过来,通过图像中的一个点找到它在三维中对应的点就很成了一个问题,因为我们并不知道等式左边的Zc的值。

光心是什么

可以把凸透镜的几何中心近似看作是光心,因为实际上两者不重合,所以才径向和切向畸变。

焦距是什么

是成像平面或者像素平面和光心之间的距离,焦距越大,人细节越清楚,视角越小;焦距越小,视野越广,但细节越看不清。
【视觉SLAM十四讲源码解读】坐标变换 像素坐标系、图像坐标系、相机坐标系、相机归一化坐标系、世界坐标系_第1张图片

总结五种坐标系的关系

按照十四讲的顺序我们首先接触的是像素坐标系、图像坐标系、相机坐标系、相机归一化坐标系、世界坐标系,这里学着学着就蒙了,所以我建议先学习投影模型,我认为二者可以理解为互逆过程,总结一下就是世界坐标和相机坐标之间要借助外参就是Rt进行转换,相机和相机归一化之间要有一个尺度的转换,这里默认尺度是Z,这里正是三维变为二维的过程,就像(10,4,2)和(5,2,1)一样忽略第三个维度,前两个维度是一样的。相机坐标系的原点是光心,图像坐标系的原点是焦点,焦点和关心之间的距离是焦距,两个相机光心之间的距离值是基线,基线乘fx除Z=视差,像素平面的原点是左上角和OpenCV的坐标系一样,像素平面和成像平面之间相差的是平移和缩放通过内参fx,fy,cx,cy实现。

五种坐标系转换原理

【视觉SLAM十四讲源码解读】坐标变换 像素坐标系、图像坐标系、相机坐标系、相机归一化坐标系、世界坐标系_第2张图片

根据三角形相似原理得出下面的公式:

Z f \frac{Z}{f} fZ = X X ′ \frac{X}{X'} XX = Y Y ′ \frac{Y}{Y'} YY

整理一下得到成像平面点和现实世界空间点之间的关系:

X ′ X' X = f ∗ X Z f*\frac{X}{Z} fZX
Y ′ Y' Y = f ∗ Y Z f*\frac{Y}{Z} fZY

假设 P ′ P' P的像素坐标为: [ u , v ] T [u, v]^T [u,v]T

像素坐标系通常的定义方式是:

原点 o ′ o' o位于图像的左上角,
u u u轴向右与 x x x轴平行,
v v v轴向下与 y y y轴平行。

像素坐标系与成像平面之间相差了一个缩放和一个原点的平移。

设像素坐标在 u u u轴上缩放了 α α α倍,在 v v v上缩放了 β β β倍。

同时原点平移了 [ c x , c y ] T [c_x, c_y]^T [cx,cy]T

那么 P ′ P' P的坐标与像素坐标 [ u , v ] T [u, v]^T [u,v]T的关系为:

u u u = α ∗ X ′ + c x α*X' + c_x αX+cx
v v v = β ∗ Y ′ + c y β*Y' + c_y βY+cy

X ′ X' X = u − c x α \frac{u - c_x}{α} αucx
Y ′ Y' Y = v − c y β \frac{v - c_y}{β} βvcy

并把 α f αf αf合并成 f x f_x fx,把 β f βf βf合并成 f y f_y fy

结合上面成像平面点和现实世界空间点之间的关系

X ′ X' X = f ∗ X Z f*\frac{X}{Z} fZX
Y ′ Y' Y = f ∗ Y Z f*\frac{Y}{Z} fZY

得到下面的像素点和空间点之间的关系

u u u = f x ∗ X Z + c x f_x*\frac{X}{Z} + c_x fxZX+cx

v v v = f y ∗ Y Z + c y f_y*\frac{Y}{Z} + c_y fyZY+cy

u − c x f x ∗ Z \frac{u-c_x}{f_x} * Z fxucxZ = X X X

v − c y f y ∗ Z \frac{v- c_y}{f_y} * Z fyvcyZ = Y Y Y

f f f的单位为米,

α α α, β β β的单位为像素每米,

所以 f x f_x fx, f y f_y fy的单位为像素。

把该式写成矩阵形式,会更加简洁,不过左侧需要用到齐次坐标:

≜ \triangleq 表示定义为,读作德尔塔等于或 Delta Equal To。

( u v 1 ) \begin{pmatrix} u \\ v \\ 1 \end{pmatrix} uv1 = ( f x 0 c x 0 f y c y 0 0 1 ) \begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} fx000fy0cxcy1 ( X Y Z ) \begin{pmatrix} X \\ Y \\ Z \end{pmatrix} XYZ ≜ \triangleq 1 Z × K P \frac{1}{Z}×KP Z1×KP

换一种写法

( u v 1 ) \begin{pmatrix} u \\ v \\ 1 \end{pmatrix} uv1 = Z × ( f x 0 c x 0 f x c y 0 0 1 ) Z×\begin{pmatrix} f_x & 0 & c_x \\ 0 & f_x & c_y \\ 0 & 0 & 1 \end{pmatrix} Z×fx000fx0cxcy1 ( X Y Z ) \begin{pmatrix} X \\ Y \\ Z \end{pmatrix} XYZ ≜ \triangleq K P KP KP

中间的量组成的矩阵称为相机的内参数矩阵(Camera Intrinsics)K

上面我们使用的 P P P是在相机坐标系下的坐标

由于相机在运动,所以 P P P的相机坐标应该是它的世界坐标(记为 P w P_w Pw ),

根据相机的当前位姿,变换到相机坐标系下的结果。

相机的位姿由它的旋转矩阵 R R R和平移向量 t t t来描述。

则有下面关系式:

Z P u v ZP_{uv} ZPuv= Z [ u v 1 ] Z\begin{bmatrix} u \\ v \\ 1 \end{bmatrix} Zuv1 = K ( R P w + t ) K(RP_w + t) K(RPw+t)= K T P w KTP_w KTPw

终于把理论部分说明白了。

这个是归一化平面的点(Z = 1)转化为像素坐标。

Vector2d Camera::camera2pixel ( const Vector3d& p_c )
{
    return Vector2d (
        fx_ * p_c ( 0,0 ) / p_c ( 2,0 ) + cx_,
        fy_ * p_c ( 1,0 ) / p_c ( 2,0 ) + cy_
    );
}

p_c ( 0,0 ) = u u u
p_c ( 1,0 ) = v v v
p_c ( 2,0 ) = 1

因为我们归一化左边用列向量表示了,所以是这样的
默认向量都用列向量表示,
所以书面写的时候才会加上一个装置的符号"T"
这个是上面公式的直接应用
成像平面点和现实世界空间点之间的关系:

X ′ X' X = f ∗ X Z f*\frac{X}{Z} fZX
Y ′ Y' Y = f ∗ Y Z f*\frac{Y}{Z} fZY

成像平面的 p ′ p' p的坐标与像素坐标 [ u , v ] T [u,v]^T [u,v]T的关系为:

u u u = α ∗ X ′ + c x α*X' + c_x αX+cx
v v v = β ∗ Y ′ + c y β*Y' + c_y βY+cy

推导出

u u u = α ∗ f ∗ X Z + c x α*f*\frac{X}{Z} + c_x αfZX+cx
v v v = β ∗ f ∗ Y Z + c y β*f*\frac{Y}{Z} + c_y βfZY+cy

α f αf αf合并成 f x f_x fx,把 β f βf βf合并成 f y f_y fy

u u u = f x ∗ X Z + c x f_x*\frac{X}{Z} + c_x fxZX+cx
v v v = f y ∗ Y Z + c y f_y*\frac{Y}{Z} + c_y fyZY+cy


这个是像素点转换到相机坐标系下面的点

Vector3d Camera::pixel2camera ( const Vector2d& p_p, double depth )
{
    return Vector3d (
        ( p_p ( 0,0 )-cx_ ) *depth/fx_,
        ( p_p ( 1,0 )-cy_ ) *depth/fy_,
        depth
    );
}

理解:
p_p ( 0,0 ) = u u u
p_p ( 1,0 ) = v v v

那么 P ′ P' P的坐标与像素坐标 [ u , v ] T [u, v]^T [u,v]T的关系为:

u u u = α ∗ X ′ + c x α*X' + c_x αX+cx
v v v = β ∗ Y ′ + c y β*Y' + c_y βY+cy

首先推导出

u − c x u - c_x ucx = α ∗ X ′ α*X' αX
v − c y v - c_y vcy = β ∗ Y ′ β*Y' βY

然后推导出

u − c x α \frac{u - c_x}{α} αucx = X ′ X' X
v − c y β \frac{v - c_y}{β} βvcy = Y ′ Y' Y

成像平面点和现实世界空间点之间的关系:

X ′ X' X = f ∗ X Z f*\frac{X}{Z} fZX
Y ′ Y' Y = f ∗ Y Z f*\frac{Y}{Z} fZY

推导出

u − c x α \frac{u - c_x}{α} αucx = f ∗ X Z f*\frac{X}{Z} fZX
v − c y β \frac{v - c_y}{β} βvcy = f ∗ Y Z f*\frac{Y}{Z} fZY

u − c x u - c_x ucx = α ∗ f ∗ X Z α*f*\frac{X}{Z} αfZX
v − c y v - c_y vcy = β ∗ f ∗ Y Z β*f*\frac{Y}{Z} βfZY

α f αf αf合并成 f x f_x fx
β f βf βf合并成 f y f_y fy

u − c x u - c_x ucx = f x ∗ X Z f_x*\frac{X}{Z} fxZX

v − c y v - c_y vcy = f y ∗ Y Z f_y*\frac{Y}{Z} fyZY


u − c x f x \frac{u - c_x}{f_x} fxucx = X Z \frac{X}{Z} ZX

v − c y f y \frac{v - c_y}{f_y} fyvcy = Y Z \frac{Y}{Z} ZY


u − c x f x \frac{u - c_x}{f_x} fxucx = X ′ X' X

v − c y f y \frac{v - c_y}{f_y} fyvcy = Y ′ Y' Y

乘上depth的原因,应该是因为下面这个公式

( u v 1 ) \begin{pmatrix} u \\ v \\ 1 \end{pmatrix} uv1 = Z × ( f x 0 c x 0 f y c y 0 0 1 ) Z×\begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} Z×fx000fy0cxcy1 ( X Y Z ) \begin{pmatrix} X \\ Y \\ Z \end{pmatrix} XYZ ≜ \triangleq K P KP KP

就不太懂那个频繁用到的函数像素坐标转相机归一化坐标
Point2d pixel2cam(const Point2d &p, const Mat &K);

Vector3d Camera::pixel2camera ( const Vector2d& p_p, double depth )

对比一下

Point2d pixel2cam(const Point2d &p, const Mat &K) {
    cout << K.at<double>(0, 2) << endl;
  return Point2d
    (
      (p.x - K.at<double>(0, 2)) / K.at<double>(0, 0),
      (p.y - K.at<double>(1, 2)) / K.at<double>(1, 1)
    );
}

首先相机内参数是这样的:

( f x 0 c x 0 f y c y 0 0 1 ) \begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} fx000fy0cxcy1

K.at(0, 2) = c x c_x cx
K.at(0, 0) = f x f_x fx
K.at(1, 2) = c y c_y cy
K.at(1, 1) = f y f_y fy

(p.x - c x c_x cx) / f x f_x fx
(p.y - c y c_y cy) / f y f_y fy

这刚好是上面代码推导出来的公式

u − c x f x \frac{u - c_x}{f_x} fxucx = X ′ X' X

v − c y f y \frac{v - c_y}{f_y} fyvcy = Y ′ Y' Y

所以这个代买求的是成像平面的坐标 可能是省略了 Z=1 所以就是归一化平面坐标了

投影模型

1、世界坐标 P w P_w Pw (路标点)通过外参数R t转换到相机坐标 P c P_c Pc

P w P_w Pw = [ X Y Z ] \begin{bmatrix}X \\Y\\Z\\\end{bmatrix} XYZ

P c P_c Pc = [ X ′ Y ′ Z ′ ] \begin{bmatrix}X'\\Y'\\Z'\\\end{bmatrix} XYZ

R ∗ P w + t R*P_w+t RPw+t = P c P_c Pc

R ∗ [ X Y Z ] + t R*\begin{bmatrix}X \\Y\\Z\\\end{bmatrix}+t RXYZ+t = [ X ′ Y ′ Z ′ ] \begin{bmatrix}X'\\Y'\\Z'\\\end{bmatrix} XYZ

2、相机坐标系下的相机坐标 P c P_c Pc投影至相机坐标系下的归一化平面的相机坐标 P c P_c Pc

P c P_c Pc = [ X ′ Z ′ Y ′ Z ′ Z ′ Z ′ ] \begin{bmatrix}\frac{X'}{Z'}\\\frac{Y'}{Z'}\\\frac{Z'}{Z'}\\\end{bmatrix} ZXZYZZ

3、归一化平面的相机坐标 P c P_c Pc转换为像素坐标

假设 P c P_c Pc的像素坐标为: [ u v ] \begin{bmatrix}u\\v\\\end{bmatrix} [uv]

相机模型:相机坐标系下的三维点与成像平面之间通过三角形相似建立关系

u u u = f x ∗ X ′ Z ′ + c x f_x*\frac{X'}{Z'} + c_x fxZX+cx
v v v = f y ∗ Y ′ Z ′ + c y f_y*\frac{Y'}{Z'} + c_y fyZY+cy

上述1、2、3、过程称为投影模型

world2camera世界坐标转化为相机坐标

Vector3d Camera::world2camera ( const Vector3d& p_w, const SE3& T_c_w )
{
    return T_c_w*p_w;
}

【视觉SLAM十四讲源码解读】坐标变换 像素坐标系、图像坐标系、相机坐标系、相机归一化坐标系、世界坐标系_第3张图片

camera2world相机坐标转化为世界坐标

Vector3d Camera::camera2world ( const Vector3d& p_c, const SE3& T_c_w )
{
    return T_c_w.inverse() *p_c;
}

camera2pixel相机坐标系下面的点转化为像素坐标

Vector2d Camera::camera2pixel ( const Vector3d& p_c ){
    return Vector2d (
               fx_ * p_c ( 0,0 ) / p_c ( 2,0 ) + cx_,
               fy_ * p_c ( 1,0 ) / p_c ( 2,0 ) + cy_
           );
}

注意这里隐含了相机到相机归一化平面的过程p_c ( 0,0 ) / p_c ( 2,0 )p_c ( 1,0 ) / p_c ( 2,0 )
先把像机坐标系下的点转化到归一化平面
P c P_c Pc = [ X ′ Y ′ Z ′ ] \begin{bmatrix}X'\\Y'\\Z'\\\end{bmatrix} XYZ

归一化之后

[ X ′ Z ′ Y ′ Z ′ Z ′ Z ′ ] \begin{bmatrix}\frac{X'}{Z'}\\\frac{Y'}{Z'}\\\frac{Z'}{Z'}\\\end{bmatrix} ZXZYZZ
在这里插入图片描述
在这里插入图片描述
归一化后转换成像素坐标(忽略畸变)

fx_ * p_c ( 0,0 ) / p_c ( 2,0 ) + cx_,
fy_ * p_c ( 1,0 ) / p_c ( 2,0 ) + cy_

u u u = f x ∗ X ′ Z ′ + c x f_x*\frac{X'}{Z'} + c_x fxZX+cx
v v v = f y ∗ Y ′ Z ′ + c y f_y*\frac{Y'}{Z'} + c_y fyZY+cy

pixel2camera像素坐标转化为像机坐标系下面的点

Vector3d Camera::pixel2camera ( const Vector2d& p_p, double depth )
{
    return Vector3d (
               ( p_p ( 0,0 )-cx_ ) *depth/fx_,
               ( p_p ( 1,0 )-cy_ ) *depth/fy_,
               depth
           );
}

实际上有一个中间过程,就是先转化为归一化平面的点
这里的depth就是归一化的 X ′ Z ′ \frac{X'}{Z'} ZX Y ′ Z ′ \frac{Y'}{Z'} ZY
在这里插入图片描述

u − c x f x \frac{u-c_x}{f_x} fxucx = X ′ Z ′ \frac{X'}{Z'} ZX

v − c y f y \frac{v- c_y}{f_y} fyvcy = Y ′ Z ′ \frac{Y'}{Z'} ZY

[ u − c x f x v − c y f y 1 ] \begin{bmatrix}\frac{u-c_x}{f_x}\\\frac{v- c_y}{f_y}\\1\\\end{bmatrix} fxucxfyvcy1 = [ X ′ Z ′ Y ′ Z ′ Z ′ Z ′ ] \begin{bmatrix}\frac{X'}{Z'}\\\frac{Y'}{Z'}\\\frac{Z'}{Z'}\\\end{bmatrix} ZXZYZZ

world2pixel世界坐标转化为像素坐标

Vector2d Camera::world2pixel ( const Vector3d& p_w, const SE3& T_c_w )
{
    return camera2pixel ( world2camera(p_w, T_c_w) );
}

X ∗ f x + c x X*f_x +c_x Xfx+cx = u u u
Y ∗ f y + c y Y*f_y + c_y Yfy+cy = v v v

pixel2world相素坐标转化为世界坐标

Vector3d Camera::pixel2world ( const Vector2d& p_p, const SE3& T_c_w, double depth )
{
    return camera2world ( pixel2camera ( p_p, depth ), T_c_w );
}

u − c x f x \frac{u-c_x}{f_x} fxucx = X X X
v − c y f y \frac{v- c_y}{f_y} fyvcy = Y Y Y

上面是针孔模型可以对比看看鱼眼EUCM模型

6自由度 如何理解需要6个坐标才能确定一个刚体的位置?

首先,在三维空间中,对于一个质点有三个自由度,需要三个坐标来确定它的位置,这一点应该无可争议。而对于一个刚体,它在三维方向有几何尺度,那么我们需要知道它的摆放方式,这种摆放方式的确定需要另外三个坐标。而为什么是三个坐标呢,因为我们需要三个夹角,刚体中的任意一条线与xyz轴的夹角,就是这三个坐标。

如何理解其次坐标用途?

【视觉SLAM十四讲源码解读】坐标变换 像素坐标系、图像坐标系、相机坐标系、相机归一化坐标系、世界坐标系_第4张图片
【视觉SLAM十四讲源码解读】坐标变换 像素坐标系、图像坐标系、相机坐标系、相机归一化坐标系、世界坐标系_第5张图片

如何理解相机外参数矩阵单应性矩阵H本征矩阵E基础矩阵F?

1.相机外参数矩阵。告诉你现实世界点(世界坐标)是怎样经过旋转和平移,然后落到另一个现实世界点(摄像机坐标)上。

2.相机内参数矩阵。内参数矩阵M:将空间三维点投影到像平面上的二维点(注意顺序关系)的矩阵。

3.单应性矩阵H:一个平面上的点到另一个平面上的点的投影映射矩阵。多视场中会用到。

4.本征矩阵E:(以双目视觉为例)将真实世界中的点P在左摄像机观测到的(左摄像机坐标系的)三维坐标Pl与右摄像机观测到的点P的(右摄像机坐标系中的)三维坐标Pl关联起来的矩阵。

5.基础矩阵F:(以双目视觉为例)将点P投影到左摄像机图像坐标系中的二维坐标和右摄像机图像坐标系中的二维坐标点关联起来的矩阵。

如何理解等距变换、相似变换、仿射变换和射影变换?

等距变换就是对图像的旋转+平移 —图像相对原图大小不变。
相似变换对图像的旋转+平移+缩放 —图像相对原图变小了一些。
仿射变换就是对图像的旋转+平移+缩放+切变(shear),相比前两种变换图像的形状发生了改变,但是原图中的平行线仍然保持平行。
射影变换就是对图像的旋转+平移+缩放+切变+射影,相比前三种变换图像的形变更为自由,原图中的平行线经过变换之后已经不在平行,而可能相交于一点,射影变换就是把理想点(平行直线在无穷远处相交)变换到图像上。应用示例是相机成像原理。

你可能感兴趣的:(从零开始学习SLAM,视觉SLAM十四讲)