[Computer Graphics]2 相机模型

视图变换(Viewing Transformation)

我们可以这样来描述视图变换的任务:将虚拟世界中以(x,y,z)为坐标的物体变换到以一个个像素位置(x,y)来表示的屏幕坐标系之中(2维),这确实是一个较为复杂的过程,但是整个过程可以被细分为如下几个步骤:

(1) 模型变换(modeling tranformation):这一步的目的是将虚拟世界中或者更具体点,游戏场景中的物体调整至他们应该在的位置
(2) 摄像机变换(camera tranformation):在游戏中我们真正在乎的是摄像机(或者说眼睛)所看到的东西,也就是需要得到物体与摄像机的相对位置
(3) 投影变换(projection tranformation):根据摄像机变换得到了所有可视范围内的物体对于摄像机的相对位置坐标(x,y,z)之后,便是根据是平行投影还是透视投影,将三维空间投影至标准二维平面([-1,1]^2)之上 (tips:这里的z并没有丢掉,为了之后的遮挡关系检测)
(4) 视口变换(viewport transformation):将处于标准平面映射到屏幕分辨率范围之内,即[-1,1]^2→ \rightarrow→[0,width]*[0,height], 其中width和height指屏幕分辨率大小

有了如上4个步骤之后,整个视图变换的过程就变的清晰了起来,如下给出一个具体例子帮助理解:
在这里插入图片描述
上图的4个箭头分别对应了上文所讲述的4个具体步骤,接下来我们就具体讲解这4个步骤到底做了什么。

1 模型变换(modeling transformation)

关于模型变换其实在开头部分便已经讲清楚了,就是利用基础的变换矩阵将世界当中的物体调整至我们想要的地方(旋转,平移,缩放)。

2 摄像机变换(camera tranformation)

Camera transformation属于比较复杂的一部分,但其实一但掌握了套路,也十分容易理解,希望我的解释能够帮助到你。

正如上文所说摄像机变换的目的是得到所有可视物体与摄像机的相对位置,怎么得到?非常直观的一步,我们把物体和摄像机一起做移动,如果能够把摄像机的坐标轴(假设为u,v,w 分别对应原世界空间中的x,y,z)移动到标准的x,y,z轴,那么此时物体的坐标不自然便是相对坐标了吗!

因此核心问题就变成了如何表示或者说如何将camera的坐标系与原世界坐标系重合呢?我们先定义3个东西

相机或眼睛位置 (eye postion) e
观察方向 (gaze postion) g
视点正上方向 (view-up vector ) t

有了这三者定义之后,我们便可以建立摄像机坐标系了,定义如下:

其中u,v,w分别对应标准坐标系下的x,y,z,示意图如下:
在这里插入图片描述
(tips:这里为什么不直接拿 t 当做基底向量是因为摄像机的头可能是歪着看的,就像图中一样 )

如此成功建立摄像机坐标系之后,如何将其移动到原世界坐标系呢?

1 将相机位置移动至原点
2 通过旋转矩阵将二者坐标系重合

第一步只需简单的减去相机位置坐标 e 即可,而第二步也曾在计算机图形学一:基础变换矩阵总结(缩放,旋转,位移)就以讲过,只需用 ( u , v , w ) T (u,v,w)^T (u,v,w)T矩阵便可轻松表示将摄像机坐标系旋转至世界坐标系了,如果不理解的读者请移步其中2.2节花个1,2分钟读一下就能明白!

相信到这整个摄像机变换的过程已经十分清楚了,我们定义该变换矩阵为 M c a m M_{cam} Mcam 定义如下:
在这里插入图片描述
(本文中所有矩阵都是左乘),最右边的矩阵代表第一步操作移至原点,旁边那个矩阵则代表第二步操作将坐标系重合。

tips:这里用了齐次坐标系表示!

3 投影变换(projection tranformation)

投影变换时除了摄像机之外另外一个重点,在经过摄像机变换之后得到的依然时三维空间中的顶点坐标,如何将其映射至二维空间坐标就交给投影变换完成。正如我们所熟知的那样投影又主要分为正交投影和透视投影,依次介绍

3.1 正交投影变换(Orthographic Projection Transformation)

在这里插入图片描述
正交投影是相对简单的一种,坐标的相对位置都不会改变,所有光线都是平行传播,我们只需将物体(可视部分,即上图的那个长方体)全部转换到一个 [ − 1 , 1 ] 3 [-1,1]^3 [1,1]3的空间之中即可(其中x,y坐标便是投影结果,保留z是为了之后的遮挡检测)

tips:这里可能会有读者疑问,为什么要压缩到一个小立方体呢?其实这只是为了之后的计算更加的方便而已,在转换到屏幕坐标的时候就会重新拉伸回来,不必太做纠结,只需抓住正交投影的变化核心是,所有物体的相对大小位置都不会有任何变化。

先定义可视空间如上图所示,其中:
在这里插入图片描述
如何将这么一个范围转换为 [ − 1 , 1 ] 3 [-1,1]^3 [1,1]3的空间呢,这其实就是一个空间的缩放,具一个简单的二维例子从 [ x l , y l ] ∗ [ x h , y h ] → [ x l ′ , y l ′ ] ∗ [ x h ′ , y h ′ ] [x_l,y_l]*[x_h,y_h]\rightarrow[x_l^{\prime},y_l^{\prime}]*[x_h^{\prime},y_h^{\prime}] [xl,yl][xh,yh][xl,yl][xh,yh]:
在这里插入图片描述
图示已然很清晰,是一个更加通用的例子,从任意一个范围转换到任意一个范围,同样也是分三步

1 将原空间范围的左下角移至原点
2 放大给定倍数
3 将缩放后的空间范围移至新空间范围
这样一个general的二维例子用矩阵来表示就是这样:
在这里插入图片描述
是不是非常直观呢,当然也可以非常简单的推广到三维,即 [ x l , y l ] ∗ [ x h , y h ] ∗ [ z l , z h ] → [ x l ′ , y l ′ ] ∗ [ x h ′ , y h ′ ] ∗ [ z l ′ , z h ′ ] [x_l,y_l]*[x_h,y_h]*[z_l,z_h]\rightarrow[x_l^{\prime},y_l^{\prime}]*[x_h^{\prime},y_h^{\prime}]*[z_l^{\prime},z_h^{\prime}] [xl,yl][xh,yh][zl,zh][xl,yl][xh,yh][zl,zh]:这里不给出计算过程,直接给出最后变换矩阵
在这里插入图片描述
这样得到了一个general的变换矩阵之后,正交投影变换只需将相应的数据带入即可,定义正交变换矩阵 M o r t h M_{orth} Morth如下:
在这里插入图片描述

3.2 透视投影变换(Perspective Projection Transformation)

透视投影就是最类似人眼所看东西的方式,遵循近大远小,如果说正交投影都是水平光线,那么透视投影则显然不是了(左透视,右正交)
在这里插入图片描述
此时,投影过程可用下图解释,将 ( x , y , z ) (x,y,z) (x,y,z)一点投影至投影屏幕之后,他的坐标变为 ( x ′ , y ′ , z ′ ) (x^{\prime},y^{\prime},z^{\prime}) (x,y,z)
在这里插入图片描述
图中原点代表视点,z = -n代表投影平面,利用相似三角形性质不难得出图中投影之后的坐标
那么利用齐次坐标的性质,希望找到一个矩阵完成如下变换:
在这里插入图片描述
即:
在这里插入图片描述
(如果形象化的描述一下的话,就是利用这个变换矩阵将整个空间压缩了一下,使其对应了真正透视投影的坐标,最后不要忘了要利用正交转换到 [ − 1 , 1 ] 3 [-1,1]^3 [1,1]3
的空间之内)

首先,这个矩阵的前两行和最后一行是能很快确定出来的,根据最后的齐次坐标,如下:
在这里插入图片描述
那么如何确定第三行呢,这里就要运用透视投影的一个性质:
可视空间,即本节第一张图的Frustum的前后面变换之后z坐标不变
1 Any point on the near plane will not change
2 Any point’s z on the far plane will not change

设第三行为(0,0,A,B) ,利用这个性质分别代入远近平面的任意两点就可以列出两个等式
A n + B = n 2 An + B = n^2 An+B=n2
A f + B = f 2 Af + B = f^2 Af+B=f2
容易解出 A = n + f , B = − n f A=n+f,B=−nf A=n+f,B=nf

得最后变换矩阵为
在这里插入图片描述
最后的一步,将这个被压缩过的空间,重新正交投影成标准小立方体,故定义透视投影变换 M p e r M_{per} Mper如下
M p e r = M o r t h o M p e r s p → − o r t h o \large{M_{per} = M_{ortho}M_{persp\rightarrow-ortho}} Mper=MorthoMpersportho
其中两个矩阵都已再上文定义过。计算结果如下:
在这里插入图片描述

4 视口变换(viewport transformation)

这一步就很简单了,一开始也介绍过就是两个范围空间的转换 [ − 1 , 1 ] 2 → [ 0 , w i d t h ] ∗ [ 0 , h e i g h t ] [-1,1]^2\rightarrow[0,width]*[0,height] [1,1]2[0,width][0,height],在正交变换一节已详细解释清楚,这里直接套公式即可
在这里插入图片描述
至此历经上述4个变换,我们就已经成功的把游戏世界的任意可视物体转换到屏幕上了!回顾一下,其实也不是很难,只要分清步骤就会十分清晰。

总结:变换 M = M v i e w M p e r M c a m M m o d e l \large{M = M_{view}M_{per}M_{cam}M_{model}} M=MviewMperMcamMmodel

相机模型

透视模型

在这里插入图片描述
我们最常见的投影模型Perspective Projection Model描述的就是针孔相机的成像原理。从上面的图根据相似三角形可以得出
在这里插入图片描述
其中 c x c_{x} cx为光轴在图像中的x坐标,如果相机的光轴与感光元器件完全对齐的话, c x = W / 2 c_{x}=W/2 cx=W/2 ,W为图片的宽度(像素)

我们最常用的将一个三维点投影到像素坐标系的时候,可以直接使用下面的公式,对应的就是针孔相机模型
在这里插入图片描述
其中P是相机坐标系下的三维点,K是相机的内参,p是像素坐标系的坐标。
上面的公式在实际计算的时候也可以写成下面的公式
在这里插入图片描述
如果我们增加将世界坐标系的点转到相机坐标系的过程,则上述的投影过程就变成
在这里插入图片描述

上面是针孔相机的成像过程,其中要注意的一点是,对于相机坐标系下的P点,其无论如何延伸,在图片上的成像点都是同一个点。也就是说,对于一个三维点,乘以一个系数,在上面这个模型中的成像点不变。这一点其实对于理解后面的其他相机模型是尤为重要的。

经典投影

成像模型既然是用来描述真实的相机镜头的投影关系,那么必然理论跟现实就会有差距。因此,研究者设计了不同的成像模型来描述不同镜头的投影关系。也可以根据这些数学模型设计真实的物理镜头。事实上,只要成像角度稍微大的镜头(可以想象鱼眼镜头),如果还是用简单的针孔模型来描述的化,偏差就会很大,因此需要不同的相机模型来描述。

经典的成像模型要有一个步骤就是把三维坐标的点先投影到单位球(Unit Sphere)上,有时候这个单位球也叫Viewing Sphere
在这里插入图片描述
来源:Omnidirectional DSO:Direct Sparse Odometry with Fisheye Cameras
这部分的一篇经典论文是:Perspective Projection:The Wrong Imaging Model
在这里插入图片描述
参考Perspective Projection: The Wrong Imaging Model;先把三维点投影到单位球上,其在图像上的成像点与图像y轴的夹角保持不变,其在图像上离原点的距离是夹角 α \alpha α的函数
在这里插入图片描述
上图中点 P = [ X s , Y s , Z s ] P=[X_{s},Y_{s},Z_{s}] P=[Xs,Ys,Zs]是三维点投影到单位圆之后的点,该点投影到图像上,与图像x轴的夹角保持不变,其到图像中心的距离是夹角 α \alpha α的函数 ρ α \rho_{\alpha} ρα,这个函数的不同形式对应着不同的经典成像模型
在这里插入图片描述
上图中来源于Models of classical projections

这篇文章比较直观的列出了5种经典投影模型的投影函数。与上文中的符号略有不同,上文中引用自论文的表达更统一,但是不太直观。上图中的 θ \theta θ可以看成是当公式(6)中的 β \beta β角为0,退化后的 α \alpha α角。于是,无论是从博文Models_of_classical_projections还是论文Perspective Projection:The Wrong Imaging Model,我们都可以得出5种经典相机模型的成像方程。这里还是以论文Perspective Projection:The Wrong Imaging Model中的表达进行描述。
在这里插入图片描述
不同成像模型半径投影方程的函数图:
在这里插入图片描述
无论是小孔成像模型还是其他模型,都可以看作是先把世界的点放缩到一个单位球。之所以可以这样做的原因是,从相机光心发射出的一条线,线上的点都会投影到同一个像素值。也就是说,我们在做投影的时候,放缩一个常量的结果是相同的。这一点在opencv的教程里是这样描述的:

Due to this mapping, all multiples k*Ph, for k≠0, of a homogeneous point represent the same point Ph. An intuitive understanding of this property is that under a projective transformation, all multiples of Ph are mapped to the same point. This is the physical observation one does for pinhole cameras, as all points along a ray through the camera’s pinhole are projected to the same image point, e.g. all points along the red ray in the image of the pinhole camera model above would be mapped to the same image coordinate. This property is also the source for the scale ambiguity s in the equation of the pinhole camera model.

这部分内容想要有一个较全面(但是很基础)的了解,可以按照以下顺序阅读:

Perspective Projection:The Wrong Imaging Model
Models_of_classical_projections (用较多的函数图描绘了不同投影方程的距离差距、成像角度差距等)
Various lens projections (使用实际图片展示不同投影模型的成像效果)

相机畸变

不同的相机模型对应了不同类型的物理镜头,但是实际中的物理镜头不可能完美地对应某一个相机模型。这里的不完美包括了镜头自身的安装误差,以及成像模型本身的表达局限性。事实上,镜头的生产厂家的主要工作之一就是设计和制作尽量贴近相机模型的镜头。

于是,成像模型与真实镜头的成像之间的差距就叫做畸变。畸变也被某个数学函数描述,可以简单地理解为畸变就是在完美的相机成像模型中间插入一个函数,使得最后得出的像素坐标跟用相机投影关系得出的坐标不一致。

但是要注意的是,畸变这个词在实际的代码中的意义并不是去除成像模型与真实物理成像过程的具体差距,使用Opencv的代码去畸变,实际上是将一张图片的成像过程矫正为使用透视投影(Perspective Projection)模型的图像。也就是说,对图像去完畸变之后,该图像的投影函数就只剩下透视投影的4个参数(fx,fy,cx,cy)表达了。

以Opencv:Camera Calibration里面的在透视投影镜头里面出现的径向畸变模型为例,本文的公式(4)实际上会变成
在这里插入图片描述
其中
在这里插入图片描述
公式(7)中的函数 g ( , ; w ) g(,;w) g(,;w)所描述的就是畸变模型。可以看到Opencv:Camera Calibration给出一种最经典的畸变模型。
在这里插入图片描述
严格上来说(我也不知道对不对),畸变这个词描述的应该是由于实际条件无法达到完美,因此使用任何一种相机模型都无法完美地描述一个物理镜头,这里面的实际误差叫做畸变。

但是对于使用Opencv或者其他工具库进行去畸变时,其中的意义是,我们用了一个高阶函数来拟合相机与小孔成像相机之间的差距,然后用优化的方法利用这个高阶函数的系数(畸变参数)对某个图像转换为用小孔成像过程成像后的图片。

也就是说,去完畸变后,你可以认为那张图片就是用小孔成像模型成像出的图片。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值