双目视觉:四种坐标系
本篇文章主要针对于机器视觉常用的坐标系的介绍以及推演,坐标系一共有四种:世界坐标系、相机坐标系、像素坐标系、图像坐标系。除了一些计算过程,还有一部分代码示例。
坐标系简介
注:本篇文章中四种坐标系都是左手坐标系,有些时候比如matlab所使用的就是右手坐标系,这个不会有太大的影响
世界坐标系
- 庞大世界中的坐标系,可以表示万物的位置
- 单位:m
- 一般表述相机位置和实物位置
- Ow-XwYwZw来表示
- Ow是原点,双目系统中可以将任意一个摄像头的光心设置成原点,即世界坐标系和相机坐标系重合
相机坐标系
- 存在于相机成像原理上,方便光的直线传播
- 单位:m
- Oc-XcYcZc来表示
- Oc是原点,相机光心的位置,所有光都汇聚这一点
像素坐标系
- 一张图片中的每个像素位置
- UV表示,但实际上有第三个坐标轴,用来表示颜色程度
- 原点在左上角
图像坐标系
- O-XY来表示
- 原点位于光轴上的一个点,用物理单位表示像素的位置
变换
世界坐标到相机坐标系
旋转
z轴是被围绕旋转的轴,z上的坐标保持不变。
图片为o-x’y’z’旋转成o-xyz的过程
写成矩阵形式:
于是旋转矩阵可以表示为三个矩阵相乘:
- 这里我们讨论一下旋转矩阵的一些性质:
- 三个旋转矩阵都是满秩(代数余子式可以算出旋转矩阵的行列式永远为1,也就是永远不会等于零)。
- 没有旋转的时候就变成了单位矩阵。
平移
平移只需要在一个坐标基础上直接加上偏移量就可以实现平移:
综合到坐标系转换
由此可以推广到世界坐标系乘上一个旋转矩阵,转换成和相机坐标系相同方向的新坐标系,但需要一个平移T将坐标系平移过去:
但上面的公式比较麻烦,写成下面的方式:
- R为旋转矩阵,(3*3)
- T为偏移向量,(3*1)
- 零向量为(1*3)
其实,我不喜欢这种形式,这种形式为了追求规整,放弃了一些比较好的特性,这个主要看个人习惯。我在接下来使用的时候为了计算方便,会再次拆开。
相机坐标系到图像坐标系
两种坐标系存在透视关系,是一种从3D转换到2D的转换,其中可以使用相似三角形进行比例计算。
图中有两个相似三角形:
从两个相似三角形中可以找到一些长度的关系:
其中有些可以用其他表示:
于是重新更改一下就变成了新的式子:
我们的目的是想表示出图像坐标系,也就是用其他变量去表示(x,y),这个时候就可以进行简单修改:
接下来就转换成矩阵形式
图像坐标系到像素坐标系
两个坐标系之间不存在旋转变换,只是原点坐标会有所差距而已
这里假设每一个像素在u轴和v轴方向上的物理尺寸为dx和dy,可以表示为:
写成矩阵形式为:
综合四种坐标系的相互变换
整合
之前讨论了每两个坐标系之间都有一套变换的方法,接下来就可以把这些方法全部综合在一起,生成一个比较复杂的公式,这个公式所表达的意思就是世界坐标和像素坐标的相互转化。
用矩阵公式表达:
接下来我们重新定义一组数据:
以上定义的两数据并没有太大的物理意义,仅仅是因为书写简单方便观看。既然有这种定义式了,那么矩阵中有些地方可以进行相乘,进一步简化:
公式中我分成了两部分,一个矩阵作为相机外参,另一个矩阵作为相机内参:
相机内参:
这个涉及到相机的构造,有些摄像头买来后,直接去测焦距像素大小可能会很麻烦,而且还不准确,所以这个矩阵一般不会用公式推导求出,这里建议采用张正友标定获取,在matlab中提供了这个程序,只要拍摄几张图片就可以直接获取相机内参。
注意:matlab中的世界坐标轴有点不太一样,使用的是世界右手坐标系,所以把y轴方向变成了反向
相机外参:
这个矩阵是描述相机位置,例如在双目系统中,将一个摄像头光心设置成世界坐标系原点时,另一个摄像头可以根据原点进行一个变换,形成了一个新的坐标。
但我并不喜欢以上公式,整个公式是一步一步推理出来的,有几个地方反而有些冗余,我按照我自己的想法稍微修改了一点:
我去点了相机内参中的最后一列和相机外参中最后一行,因为在整体计算中并没有什么作用,以上两个公式都可以使用,主要是怎么方便就用哪个公式去写代码。
如果还想再简化一下,就可以写成这样:
这里的C是一个3*4的矩阵,简化成这样,里面具体的元素已经没有太大的物理含义了,但这样书写有个好处,提前计算出C之后就可以直接使用C来计算整个算式。
通过以上公式,很容易做到三维空间中的一个点在图像中的像素坐标,但反过来就,通过图像中的一个点找到它在三维中对应的点就很成了一个问题,因为我们并不知道等式左边的Zc的值。
像素和世界的相互转换
- 注:接下来的操作一定要知道深度(Zc或Zw)才能进行,虽然我们目的是求深度,但不影响我们使用下面的几个公式:
像素坐标转换成世界坐标
我把公式(3)改一下:
仅仅是把Zc移到了右边,其实如果世界坐标和相机坐标系重合的话,Zc=Zw。
整个函数的意思是,如果我们知道了世界坐标中具体的某一点坐标三个数值,就可以直接带入,求出u,v。
世界坐标转换成像素坐标
这时候我们不能去用公式(3)去修改,我们可以换个思路,使用公式(2)去修改:
由于公式(2)中的相机内参是一个3*3的对角矩阵,而且很明显是一个可逆矩阵(对角中不会出现0),那么就可以求出这个矩阵的逆矩阵,写成以下形式:
简单计算一下,等号左边最后计算的结果是一个3*1的矩阵,右边部分我们换个思路,回想一下外参矩阵的推演过程,我们可以写成这样:
那么所有矩阵往左边移动:
虽然在双目系统中,我们做不到提前给出Zc或Zw,所以以上公式进行参考即可,在一定程度上还是比较方便。
程序
1 | import numpy as np |