相机成像的过程实际是将真实的三维空间中的三维点映射到成像平面(二维空间)过程,可以简单的使用小孔成像模型来描述该过程,以了解成像过程中三维空间到二位图像空间的变换过程。
本文包含两部分内容,首先介绍小孔成像模型的各种几何关系;接着描述了成像过程中的四种坐标系(像素坐标,图像坐标,相机坐标,世界坐标)的变换关系。

小孔成像模型

相机可以抽象为最简单的形式:一个小孔和一个成像平面,小孔位于成像平面和真实的三维场景之间,任何来自真实世界的光只有通过小孔才能到达成像平面。因此,在成像平面和通过小孔看到的真实三维场景存在着一种对应关系,也就是图像中的二维像点和真实三维世界的三维点存在某种变换关系。找到了这种变换关系,就可以利用图像中的二维点信息来恢复场景的三维信息。

下图是小孔成像的模型,为了简化模型,将成像平面放在了小孔的前面,并且成的像也是正立的

在描述小孔的成像过程前,首先来定义两个坐标系:

  • 相机坐标系(三维坐标系)
    相机的中心被称为焦点或者光心,以焦点\(O_c\)为原点和坐标轴\(X_c,Y_c,Z_c\)组成了相机坐标系
  • 图像坐标系(二维坐标系)
    成像平面中,以成像平面的中心\(O'\)为原点和坐标轴\(x',y'\)组成了图像坐标系

小孔成像实际就是将相机坐标系中的三维点变换到成像平面中的图像坐标系中的二维点。

假设,三维空间中点\(P\),其在相机坐标系中的坐标是\(P_c=[X,Y,Z]^T\);其像点\(p\),在图像坐标系的中的坐标是\(p=[x,y]^T\),由于光轴垂直与成像平面,那么可以知道像点\(p\)在相机坐标系中的坐标是\(p=[x,y,z]^T,其中z =f(f是焦点到成像平面之间的距离,被称为焦距)\)。

由上图根据三角形的相似关系,可以得到如下公式:
\[
\frac{Z}{f}=\frac{X}{x}=\frac{Y}{y}
\]
将上面公式整理后可以得到:
\[
\left\{
\begin{array}{l}
x = f\frac{X}{Z} \\
y = f\frac{Y}{Z} \\
z = f
\end{array}
\right.
\]
上面的公式就是小孔相机模型的基础公式了,有了此公式可以推导出更详细的小孔相机模型的参数:

  • 内参数
  • 外参数

在推导相机的内参数和外参数前,需要先了解下齐次坐标的概念。

齐次坐标

相机的成像过程实际是将三维空间的点\(P=(X,Y,Z)\)变换到成像平面的过程,这个过程也可以被称为射影变换(更多关于射影变换的内容可参考《计算机视觉中的多视图几何》)。如上面描述的,设射影变换的中心\(O\)作为相机坐标系的原点,该点到成像平面的距离为\(f\),\(P\)在成像平面的投影点为\(p=(x,y)\),根据相似三角形原理,可以得到公式:
\[
\left\{
\begin{array}{l}
x = f\frac{X}{Z} \\
y = f\frac{Y}{Z} \\
z = f
\end{array}
\right.
\]
上面的公式就描述了三位空间到二维平面的映射,但是该映射对于坐标\(Z\)来说却是非线性(作为分母),通过上面的公式方便的统一处理\(X,Y,Z\)这三个坐标轴的数据。就需要引入新的坐标(扩展坐标的维度)将其线性化,如下:
\[
\left[\begin{array}{c}x\\y\end{array}\right] \Leftrightarrow
\left[\begin{array}{c}\hat{x}\\\hat{y}\\\hat{z}\end{array}\right] =
\left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right]
\left[\begin{array}{c}X\\Y\\Z\\1\end{array}\right]
\]
这样,可以使用矩阵的乘法统一的处理\(X,Y,Z\)这三个坐标。
坐标\((\hat{x},\hat{y},\hat{z})\)就是像点\(p=(x,y)\)的齐次坐标,其中
\[
\left\{\begin{array}{l}x=\frac{\hat{x}}{\hat{z}}\\y=\frac{\hat{y}}{\hat{z}}
\\z\ne0\end{array}\right.
\]
通过上面的公式可以很容易的推导出,怎么通过扩展坐标维度构建齐次坐标。具体步骤就是将x和y同时除以一个不为0的z,并且将z作为其添加维度的坐标,通常可以选择\(z=1\)。
这就可以发现其次坐标的一个重要性质,齐次坐标缩放一个常量因子是不变:
\[
s(a,b,c)^T=(sa,sb,sc)^T
\]

内参数

相机的内参数由下面的两部分组成:

  • 射影变换本身的参数,相机的焦点到成像平面的距离,也就是焦距\(f\)。
  • 成像平面坐标系像素坐标系的变换。上面推导中使用的像点坐标\(p=(x,y)\)是成像平面坐标系下,以成像平面的中心为原点。而实际像素点的表示方法是以像素来描述,坐标原点通常是图像的左上角,X轴沿着水平方向向左,Y轴竖直向下。像素是一个矩形块,这里假设其在水平和竖直方向的长度分别为:\(\alpha\)和\(\beta\)。所以像素坐标和成像平面坐标之间,相差了一个缩放原点的平移
    假设像素坐标的水平方向的轴为\(\mu\),竖直方向的轴为\(\nu\),那么将一个成像平面的坐标\((x,y)\)在水平方向上缩放\(\alpha\)倍,在竖直方向上缩放\(\beta\)倍,同时平移\((c_x,c_y)\),就可以得到像素坐标系的坐标\((\mu,\nu)\),其公式如下:
    \[
    \begin{array}{c}
    u = \alpha\cdot x+ c_x \\
    v = \beta \cdot y + c_y
    \end{array}
    \]
    将上面求得的\((x,y)\)带入上面公式可得到:
    \[
    \left\{\begin{array}{c}
    u = \alpha\cdot f\frac{X}{Z}+ c_x \\
    v = \beta \cdot f\frac{Y}{Z} + c_y
    \end{array}\right. \Rightarrow \left\{\begin{array}{c}
    u = f_x\frac{X}{Z}+ c_x \\
    v = f_y\frac{Y}{Z} + c_y
    \end{array}\right. 其中,f_x = \alpha \cdot f,f_y = \beta \cdot f
    \]
    将上面的公式写为齐次坐标的形式:
    \[
    \left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \frac{1}{Z}\left[
    \begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right]\left[\begin{array}{c}X\\Y\\Z\end{array}\right]
    \]
    上面提到对于齐次坐标,缩放一个常量因子仍然是相等的,将\(Z\)挪到左边
    \[
    \left[\begin{array}{c}\mu\\\nu\\1\end{array}\right]=Z\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] =\left[
    \begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right]\left[\begin{array}{c}X\\Y\\Z\end{array}\right]
    \]

通过上面的的推导,就得到了相机的内参数矩阵(Camera Intrinsics)K
\[
K=\left[
\begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right]
\]
K有4个未知数和相机的构造相关,\(f_x,f_y\)和相机的焦距,像素的大小有关;\(c_x,c_y\)是平移的距离,和相机成像平面的大小有关。
求解相机内参数的过程被称为标定,在SLAM中可以假定相机的内参是已知的,而在三维重建中内参数则是未知的,需要手动的标定(比如使用标定板),也有自标定的方法,不过精度较低。

外参数

通过上面的推导,知道了相机成像的过程
\[
p = KP
\]
其中,\(p\)是图像中像点的像素坐标,\(K\)是相机的内参数矩阵,\(P\)是相机坐标系下的三维点坐标。
上面推导使用的三维点坐标是在相机坐标系下的,相机坐标系并不是一个“稳定”的坐标系,其会随着相机的移动而改变坐标的原点和各个坐标轴的方向,用该坐标系下坐标进行计算,显然不是一个明智的选择。需要引进一个稳定不变坐标系:世界坐标系,该坐标系是绝对不变,SLAM中的视觉里程计就是求解相机在世界坐标系下的运动轨迹。

设\(P_c\)是\(P\)在相机坐标系坐标,\(P_w\)是其在世界坐标系下的坐标,可以使用一个旋转矩阵\(R\)和一个平移向量\(t\),将\(P_c\)变换为\(P_w\)
\[
P_c = RP_w + t
\]
其中,\(R\)是一个\(3\times3\)的旋转矩阵,\(t\)是\(3\times1\)的平移向量,上面运算的过程还需要做加法运算,为了方便计算,现将其改写为齐次坐标的形式
\[
\left[\begin{array}{c}X_c\\Y_c\\Z_c\end{array}\right] = \left[\begin{array}{ccc}R_{11}&R_{12}&R_{13}\\R_{21}&R_{22}&R_{23}\\R_{31}&R_{32}&R_{33}\end{array}\right]\left[\begin{array}{c}X_w\\Y_w\\Z_w\end{array}\right] + \left[\begin{array}{c}t_1\\t_2\\t_3\end{array}\right]
\]
其齐次坐标的形式
\[
\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] = \left[\begin{array}{ccc}R_{11}&R_{12}&R_{13}&t_1\\R_{21}&R_{22}&R_{23}&t_2\\R_{31}&R_{32}&R_{33}&t_3\\0&0&0&1\end{array}\right]\left[\begin{array}{c}X_w\\Y_w\\Z_w\\1\end{array}\right]
\]
将旋转矩阵\(R\)和平移向量\(t\)带入
\[
\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] = \left[\begin{array}{cc}R&t\\0^T&1\end{array}\right]\left[\begin{array}{c}X_w\\Y_w\\Z_w\\1\end{array}\right]
\]

上面就推导得到相机的外参数(Camera Extrinsics)T
\[
T = \left[\begin{array}{cc}R&t\\0^T&1\end{array}\right]
\]
其中,\(R\)是旋转矩阵,\(t\)是平移向量.

内外参数组合到一起

\(p=(\mu,\nu)\)是图像中的像点,其坐标系是像素坐标系;\(P_c=(X_c,Y_c,Z_c)\)是场景中的三维店,其坐标系是相机坐标系
\[
\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[
\begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right]\left[\begin{array}{c}X_c\\Y_c\\Z_c\end{array}\right]
\]
为了能够和外参数联合,需要将上式齐次化
\[
\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[
\begin{array}{ccc}f_x&0&c_x&0\\0&f_y&c_y&0\\0&0&1&0\end{array}\right]\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right]
\]
这里使用的三维点坐标\(P_c\)是相机坐标系下的,带入外参数,将其该坐标变换为世界坐标系\(P_w=(X_w,Y_w,Z_w)\)
\[
\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[
\begin{array}{ccc}f_x&0&c_x&0\\0&f_y&c_y&0\\0&0&1&0\end{array}\right]\left[\begin{array}{cc}R&t\\0^T&1\end{array}\right]\left[\begin{array}{c}X_W\\Y_W\\Z_W\\1\end{array}\right]
\]
可以将内外参数组合到一起称为相机矩阵,其作用是将真实场景中的三维点投影到二维的成像平面。

总结

本文总结了将场景中的三维点投影到二维成像平面变为像点的过程,下面对本文再作个总结。
设有一像点\(p=(x,y)\)其对应的场景中的三维点为\(P_c=(X_c,Y_c,Z_c)\),成像平面距离相机中心的距离为\(f\),依据小孔成像的原理,得到下面的变换公式
\[
\left[\begin{array}{c}x\\y\\1\end{array}\right] =
\left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right]
\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right]
\]
上式左边的像点坐标是成像平面坐标系下的坐标,需要将其变换到像素坐标系下。成像平面坐标系和像素坐标系间相差一个缩放和一个原点的平移
\[
\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] =
\left[\begin{array}{ccc}\frac{1}{dx}&0&c_x\\0&\frac{1}{dy}&c_y\\0&0&1\end{array}\right]
\left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right]
\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right]
\]
其中,\(dx,dy\)为一个像素的长和高,在前面的描述中使用\(\alpha = \frac{1}{dx},\beta=\frac{1}{dy}\)表示;\(c_x,c_y\)表示原点的平移量。

在上式的右边三维点的坐标\(P_c\)使用的是相机坐标系,而相机位置却不是固定不变的,需要将其变换到世界坐标系下;从相机坐标系变换到世界坐标系下需要一个旋转平移
\[
\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] =
\left[\begin{array}{ccc}\frac{1}{dx}&0&c_x\\0&\frac{1}{dy}&c_y\\0&0&1\end{array}\right]
\left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right]
\left[\begin{array}{cc}R&t\\0^T&1\end{array}\right]
\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right]
\]

一个相机矩阵就由上面三个矩阵组成。

终于完了,写之前没想到会写这么多...

SLAM入门之视觉里程计(2):相机模型(内参数,外参数)的更多相关文章

  1. SLAM入门之视觉里程计(5):单应矩阵

    在之前的博文OpenCV,计算两幅图像的单应矩阵,介绍调用OpenCV中的函数,通过4对对应的点的坐标计算两个图像之间单应矩阵\(H\),然后调用射影变换函数,将一幅图像变换到另一幅图像的视角中.当时 ...

  2. SLAM入门之视觉里程计(1):特征点的匹配

    SLAM 主要分为两个部分:前端和后端,前端也就是视觉里程计(VO),它根据相邻图像的信息粗略的估计出相机的运动,给后端提供较好的初始值.VO的实现方法可以根据是否需要提取特征分为两类:基于特征点的方 ...

  3. SLAM入门之视觉里程计(6):相机标定 张正友经典标定法详解

    想要从二维图像中获取到场景的三维信息,相机的内参数是必须的,在SLAM中,相机通常是提前标定好的.张正友于1998年在论文:"A Flexible New Technique fro Cam ...

  4. SLAM入门之视觉里程计(2):两视图对极约束 基础矩阵

    在上篇相机模型中介绍了图像的成像过程,场景中的三维点通过"小孔"映射到二维的图像平面,可以使用下面公式描述: \[ x = MX \]其中,\(c\)是图像中的像点,\(M\)是一 ...

  5. SLAM入门之视觉里程计(3):两视图对极约束 基础矩阵

    在上篇相机模型中介绍了图像的成像过程,场景中的三维点通过"小孔"映射到二维的图像平面,可以使用下面公式描述: \[ x = MX \]其中,\(c\)是图像中的像点,\(M\)是一 ...

  6. SLAM入门之视觉里程计(4):基础矩阵的估计

    在上篇文章中,介绍了三位场景中的同一个三维点在不同视角下的像点存在着一种约束关系:对极约束,基础矩阵是这种约束关系的代数表示,并且这种约束关系独立与场景的结构,只依赖与相机的内参和外参(相对位姿).这 ...

  7. SLAM——视觉里程计(一)feature

    从现在开始下面两篇文章来介绍SLAM中的视觉里程计(Visual Odometry).这个是我们正式进入SLAM工程的第一步,而之前介绍的更多的是一些基础理论.视觉里程计完成的事情是视觉里程计VO的目 ...

  8. 视觉slam十四讲个人理解(ch7视觉里程计1)

    参考博文::https://blog.csdn.net/david_han008/article/details/53560736 https://blog.csdn.net/n66040927/ar ...

  9. 第三篇 视觉里程计(VO)的初始化过程以及openvslam中的相关实现详解

    视觉里程计(Visual Odometry, VO),通过使用相机提供的连续帧图像信息(以及局部地图,先不考虑)来估计相邻帧的相机运动,将这些相对运行转换为以第一帧为参考的位姿信息,就得到了相机载体( ...

随机推荐

  1. java操作solr实现查询功能

    一.封装的查询方法 /** * solr查询方法 * @param client solr客户端 * @param query solr查询对象 * @return list集合 * @throws ...

  2. Java中Comparable和Comparator比较

    1.Comparable 介绍 Comparable 是一个排序接口,如果一个类实现了该接口,说明该类本身是可以进行排序的.注意,除了基本数据类型(八大基本数据类型) 的数组或是List,其余类型的对 ...

  3. 自定义统一api返回json格式(app后台框架搭建三)

    在统一json自定义格式的方式有多种:1,直接重写@reposeBody的实现,2,自定义一个注解,自己去解析对象成为json字符串进行返回 第一种方式,我就不推荐,想弄得的话,可以自己去研究一下源码 ...

  4. 插入排序-Python与PHP实现版

    插入排序Python实现 import random a=[random.randint(1,999) for x in range(0,36)] # 直接插入排序算法 def insertionSo ...

  5. ASP.NET Core 认证与授权[7]:动态授权

    ASP.NET Core 中基于策略的授权旨在分离授权与应用程序逻辑,它提供了灵活的策略定义模型,在一些权限固定的系统中,使用起来非常方便.但是,当要授权的资源无法预先确定,或需要将权限控制到每一个具 ...

  6. React+Redux实现追书神器网页版

    引言 由于现在做的react-native项目没有使用到redux等框架,写了一段时间想深入学习react,有个想法想做个demo练手下,那时候其实还没想好要做哪一个类型的,也看了些动漫的,小说阅读, ...

  7. Python案例分享

    1.过桥(爬金字塔): 1 i = 1 2 while i <= 9: 3 if i < 6: 4 j = 0 5 while j < i: 6 print('*',end=' ') ...

  8. 我们是80后 golang入坑系统

    现在这个系列,已经开始两极分化了. 点赞的认为风格轻松,看着不困.反之,就有人嫌写的罗里吧嗦,上纲上线.所以善意提醒,里面不只是技术语言,还有段子.专心看技术的,千万别点!别怪我没提醒!差点忘说,版权 ...

  9. [Docker网络]模拟一台交换机的拓扑

    [Docker网络]模拟一台交换机的拓扑 本例主要对Docker网络进行实际运用. 背景介绍 一台虚拟机如何模拟成一台多端口交换机分别连接多台虚拟机? bridge网桥技术 实验准备 docker d ...

  10. 条件注释判断IE版本

    在学习Bootstra的时候看到这么一句话, <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media ...