前言
常言道,工欲善其事,必先利其器。如欲明其理,必先定其义。
后一句是我编的。
不过,这句话还是有道理的。如果要想明白相机的坐标系之间的转换,那么必须明白相机有哪几个坐标系,并对它们下一个明确的定义。只有这样,我们接下来的工作才好开展。
正文
相机的坐标系,总共有四个,有的文章里面说是三个。不管三个,还是四个,说的都是一样的意思。在本篇文章里,我们按照四个坐标系来讲。现在,我们把它们的定义摆出来:
- 图像的像素坐标系(u,v)
以图像的左上方为原点,u轴平行于图像面水平向右,v轴垂直于u轴向下,此坐标系的单位为像素; - 图像的物理坐标系(x,y)
以相机的光轴与图像平面交点为原点,x轴方向与u轴方向一致,y轴方向与v轴方向一致,以毫米为单位,用物理单位表示图像像素位置; - 相机坐标系(Xc,Yc,Zc)
以相机的光心作为原点,Zc轴与光轴重合,并垂直于成像平面,且取摄影方向为正方向;Xc、Yc轴分别与图像物理坐标系的x,y轴平行;相机坐标系的原点与图像物理坐标系原点之间的距离为相机的焦距f,以毫米为单位; 世界坐标系(Xw,Yw,Zw)
三维世界的全局坐标系,以(Xw,Yw,Zw)来表示,满足右手法则;在对四个坐标系有了明确的定义之后,我们就可以开始对它们之间的关系做一些研究。
我们说的四个坐标系全在下面这张图里,虽然地方小了点儿,但坐标系一个不少,大家可以看一眼,直观地了解一下,虽然并没什么用。
1.图像像素坐标系与物理坐标系之间的转换
如前文所述,我们设
o0
点为像素坐标系的原点,它位于图像的左上顶点。u轴向右为正方向,v轴向下为正方向。
[ps一句:左上角作为像素坐标的原点,这是一种人为的设置。换句话说,我们也可以设置其它顶点作为原点。例如,在opencv里面,像 素的原点即为左上角;而在kinect拍到的图片里,则左下角为原点。有涉及到这方面的小伙伴可以做笔记了,重点已经画出来了。]
与像素坐标系原点不同,图像物理坐标系原点的定义是只此一家,别无分店。我们给物理坐标系原点起个外号:
o1
。 设
o1
的像素坐标值为
(uo,vo)
。很显然,它们之间的转换关系如下:
不过,事情并不是这么简单,由于各种原因,像素在实际当中并非方方正正的正方形,而是菱形,如下图所示。
这样一来,为了追求更高的精度,我们需要将这个因素考虑进去,当然,没把这个因素考虑进去也无妨,因为好多人都没这么办,譬如大名鼎鼎的opencv,
上图出自 opencv2.4.13的文档。相比较像素坐标带来的误差,镜头畸变带来的误差影响更大,因为镜头畸变的原因,相机其实并非线性模型,提高相机标定精度的一大方法就是采用更精确的非线性模型,对比opencv不同版本的文档,我们可以发现,opencv下功夫的也是这方面。
把话题回到主线上来,在考虑到像素坐标的实际形态之后(个人比较喜欢用”形态“这个词),像素坐标系和物理坐标系之间的关系其实是这个样子的:
与公式(3)的模型相比,opencv的模型是不是显得单纯好多。
2.图像物理坐标系与相机坐标系之间的转换
上面这幅图形象的表明了图像物理坐标系与相机坐标系之间的关系。这两者之间的变换是透视变换。
假设在空间某一点
P
,它在相机坐标系中的坐标为
其中, f 就是我前面所说的焦距,什么,我没说过?那,现在说也不迟:
照例,我们把它变成矩阵形式:
很明显,这个矩阵是一个齐次矩阵,我们为什么要变矩阵变换成齐次形式呢。简单点说,为了求解方便。
3.相机坐标系与世界坐标系之间的转换
这两者之间的变换是刚体变换。所谓刚体变换,就是只有旋转和平移的变换。
什么,难道还要别的变换?
当然有,缩放、扭曲、翻转还有剪切等等,各种变换真是不要太多。
形象点说,你拿一条棍子甩来甩去,这叫刚体变换。如果你拿一根面条甩来甩去,那就不是刚体变换。
好了,刚体变换的话题到此结束,我们来进入正题,看看相机坐标系与世界坐标系之间的转换。
其中, R 为3×3的矩阵,
利用上面的四个变换公式,我们可以得到图像的二维像素点与对应的三维空间坐标点的转换公式:
其中, s=1zc , α=fdx,β=fdy ,值得一提的是, 0T 是一个3×3的矩阵。另外 s <script type="math/tex" id="MathJax-Element-2287">s</script>并不影响矩阵的求解,具体原因,下回再说。
后记:第一篇带这么多公式的博客写完了,真是太开心