摄像机模型与标定
TODO
第15页
OCR文字识别结果:
第11章
$-f §
始,通过透镜到达眼睛或摄像机,然后到达视网膜或者图像采集器的这个过程的几
何研究,是实用计算机视觉中的一个尤其重要的方面。
一个简单而有用的解释这种现象的模型就是针孔摄像机模型。。针孔是二堵想像中
的墙(中心有一个微型小孔),光线只能从这个开口中通过,而其余的都被场所阻
挡。在本章,我们将从一个针孔摄像机模型开始,处理基本几何中的投影射线。遗
憾的是,真实的针孔由于不能为快速曝光收集足够的光线,因此它不是一个得到图
像的好方法。这也是为什么眼睛和摄像机都要使用透镜而不是仅仅只用一个点来收
集更多光线的原因。然而,这种利用透镜得到更多的光线的缺点是,不仅使我们背
离了所使用的简单针孔几何模型,而且引人来自透镜的畸变。
在本章中,我们将学习如何利用摄像机标定(camera calibration),来矫正(数学方式)
因使用透镜而给针孔模型带来的主要偏差。摄像机标定的重要性还在于它是摄像机
基于透镜的知识至少可以上溯到古罗马时期。针孔摄像机模型则至少上溯到公元987
年哈桑[102\](译者注阿拉伯著名数学家)的理论,它是介绍视觉儿何方面的经典方
法。在十七、十八世纪,伴随着笛卡儿、开普勒、伽利略、牛顿、霍克、欧拉、费
马、施耐尔等人的贡献,数学和物理学不断发展并成长(见0'Connor [0'Connor02】)。
一些几何视觉方面的关键内容包括Trucco [Trucco98],Jaehne(有时也称JMne)
Uaehne95 ; Jaehne97], Hartley 与 Zisserman [Hartley06], Forsyth 与 Ponce [Forsyth03],
Shapiro 与 Stockman [Shapiro02], f · Xu 与 Zhang [Xug 同等.
406第11章
第16页
OCR文字识别结果:
量与真实三维世界测量的联系桥梁,场景不仅仅是三维的,也是用物理单位度量
&*fj.''"71]
像机标定的过程既给出摄像机几何模型,也给出透镜的畸变模型。这两个模型定
了摄像机的内参数(intrinsic parameter)。本章将应用这些模型来矫正透镜畸变。
零
摄像机模型和透镜畸变开始。在这里,我们将研究单应变换(homograph
),它是一种能够描述摄像机基本行为特性和各种失真、矫正特性的数学
们将花费一点时间来仔细讨论如何以数学方式描述和计算这种变换。一旦
这个工具,就可以转移到OpencV函数完成大部分工作。
章阐述的所有知识是为了建立足够的理论基础,以便读者能够完整理解OpencV
,并且知道其外表下的内涵。这对正确使用该函数是
常重要的。这里说明一下,如果读者已经是一个专家或者只是想简单地了解如何
用OpencV的相关函数,那么可以直接转到后面的。标定函数。一节。
,摄像机模型
我们先看摄像机模型中最简单的针孔模型。在此模型中,想像着光线是从场景或很
远的物体发射过来的,但仅仅是来自某点的一条光线。在实际针孔摄像机中,该点
被。投影。到成像表面。其结果是在图像平面(也称为投影平面,projective plane)
上,图像被聚焦。因此与远处物体相关的图像大小只用一个摄像机参数来描述焦
距(focal length)。对于假想的针孔摄像机,从针孔到屏幕的距离就是焦距。如图
】】一】所示,f是摄像机焦距,Z是摄像机到物体的距离,X是物体长度,·是图像平
面上的物体图像。其数值可以通过相似三角形-x/f= X/Z得到,或
分
重新把针孔摄像机模型整理为另一种等价形式,使其数学形式更简单一些。在图
11-2中,我f门交换针孔和图像平面®,主要的差别是现在物体出现在等式右边。针
孔中的点被理解为投影中心(center of pro.iection)。这样,每一条光线,从远处物体
国这种数学抽象无法在物理上重构。图像平面可以简单地设想为所有抵达投影中心的光
束的。切片。。这种处理更容易绘制而且数学上的处理也更容易。
熟画
画画画
第17页
OCR文字识别结果:
的某个点出发,到达投影平面的中心。光轴与图像平面的交点被称为主点(principal
point)。在这个与旧的投影平面(或图像平面)等价的新前端图像平面上(见图11-2),
远处物体的图像与图11-1中的图像大小完全一致。光束与图像平面的相交生成图
像,而平面到投影中心的距离是人这样形成更容易理解的三角形相似关系xlf=
刀Z.负号被去掉了,因为目标图像不再是倒立的。
图11-1针孔摄像机模型。过空间某特定点的光线才能通过针孔,这些光束被
投影到图像平面形成图像
石
图1 1-2点Q=(X,Y,Z)由通过投影中心的光线投影到图像平面上,相应的
图像点为口=(z,y,f)。图像平面实际上就是把投影屏幕放置到针孔的前方(数
学上等价,但形式简单些)【37 1-372】
你也许认为主点即等于成像仪的中心,但这意味着某些人拿着镊子和胶水要把摄像
机里面的成像仪以微米级别的精度安装。实际上,芯片的中心通常不在光轴上。我
们因此引人两个新的参数C.和Cy。对可能的偏移(对光轴而言)进行建模。这样物,一
408第11章
第18页
OCR文字识别结果:
歹匡
理世界中的点Q,其坐标为(X,Y,Z),以某些偏移的方式投影为点(xsc...。。y......),
如下所示o
。_-f.C蚤)..,夕——一f,C)··,
注意,我们引人了两个不同的焦距。原因是单个像素点在低价成像仪上是矩形而不
是正方形的。例如,焦距f,实际上是透镜的物理焦距长度与成像仪每个单元尺寸s.
的乘积(这样做的意义在于s.的单位是像素/每毫米@,而F的单位是毫米,这意味
着f,的单位是像素)。同样的道理也适用于f,和Sy。请记住,s.和s,以及物理焦距
F均不能在摄像机标定过程中直接测量,只有组合量f.=Fs,和f.-Fs,可以直接计算
出来而不必拆除摄像机去直接测量其部件。
基本投影几何
将坐标为(石,片,Z.的物理点Q,映射到投影平面上坐标为(xi,vi)的点的过程叫投影变换
(projective transform)。采用这种变换,可以方便地使用我们所熟知的齐次坐标。一齐次
坐标把维数为n投影空间上的点用(n+l)维向量(如x,.。,·变为马儿z,w)表示,其额外
限制是任何两点的交比不变。在这里,图像平面是一个二维投影空间,因此可以用一
个三维向量q-(q,,q2,q3)来表示该平面上的点。因为投影空间上所有点的交比不变,
因此可以通过除以q3计算实际的像素坐标值。这样允许我们将定义摄像机的参数蚀日f.,
二cx和田重新排列为一个3 × 3的矩阵,该矩阵称为摄像机的内参数矩阵(camera
intrinsics matrix,在OpencV中,摄像机内参数矩阵的计算来自Heikkila和Siiven
[Heikkila97])。那么将物理世界中的点投影到摄像机上,可以用下式表示
展开该式,可以发现w-Z,并且点q是齐次坐标形式。除以w(或Z),就可以恢复
以前的定义。(没有减号是因为我们是在针孔前面来观看投影平面的非倒立图像,
而不是在针孔后面看投影平面的倒立图像)。【373~374】
®这里下标°screen。是说明计算出的坐标是屏幕(或成像仪)上面的坐标。方程式中
(x.....。,.。。。。。)和图11-2中(x.y)的差别在于c.和c,所描述的点。所以,我们用
"screen。下标来描述成像仪坐标。
园当然,。毫米。仅仅是一个独主的度量单位,也可以是。米。或者其他。关键在于s.
将物理单位转换为像素单位。
摄像机模型与标定409
第19页
OCR文字识别结果:
讨论齐次坐标的时候,OpencV库中有一个函数cvconvertpointsHomo一
genious o o,使用该函数可以很方便地对齐次坐标进行转换。该函数在很多其他
场合也非常有用。
void cvconvertpointsHomogenious(
const CvMat* src,
CvMat"dst
不要被简单的变量所迷惑工程序做了一整套有用的事情。输入的数组src可以是
越。,xN或Nx M,.八这里越。,-2,3或4),也可以是l×N或者N× 1,其中M..,
一2,3或4通道(N可以是任意数,它实际上是src中要转换的点的个数)。输出数
组己st可以是任意形式,只是砥。,的维数必须与此。。,M...-1或然。,+l一致。
当输入维数械。,等于输出维数竭。,,数据就是简单的复制(而且如果必要,则进行
转置)。如果M...〉竭s!,那么用目s·的元素除以src中对应向量的所有但最后一
个元素除外(也就是说,s·c假设为齐次坐标)。如果越。,〈Mdst,那么所有点被复
制到dst,并且将1插人到dst数组中每个向量的末尾。在这些场合,如同偶尔
出现的越。,一蜗、,情况下,都做必要的转置。
注意关于该函数,需要提醒一下,在某种情况(如N〈5)下输人和输出维数是不确
定的。这样函数会抛出异常。如果发现这种现象,可以用某些伪造的数据
排列到矩阵后面。另外,有时用户会传入多通道Nxl或lxN矩阵,其中
通道数目为此。,(Md s山此时可以使用函数cvReshape(」将单通道矩阵转换
为多通道矩阵而不用复制任何数据。【374】
采用理想针孔,我们有了一个对视觉中的三维几何有用的模型。但请记住,由于只
有很少量的光线通过针孔,这导致实际情况下因曝光不足使得图像生成得很慢。对
要快速生成图像的摄像机而言,必须利用大面积且弯曲的透镜,让足够多的光线能
够收敛聚焦到投影点上。为了实现该目的,我们用透镜。透镜可以聚焦足够多的光
线到某个点上,使得图像的生成更加迅速。其代价就是引人了畸变。
透镜畸变
理论上讲是可能定义一种透镜而不引人任何畸变的。然而现实世界没有完美的透
®是的,。Ho田ogenious。拼写错误。
第20页
OCR文字识别结果:
酽匿
隳。这主要是制造上的原因,因为制作一个。球形。透镜比制作一个数学上理想的
§i}$ii!£t2Fi"- 形 里
E ·
对径向畸变,成像仪中心(光学中心)的畸变为O,随着向边缘移动,畸变越来越严
重。实际情况中,这种畸变比较小,而且可以用r-俨位置周围的泰勒级数展开的
手;前几项来定量描述。对便宜的网络摄像机,我们通常使用前两项,其中第一项通常
®透镜畸变建模方法主要来自于Brown [Brown7】]以及更早的Fryer和Brown
[Fryer86].
圆如果不懂泰勒级数的定义,也不要过于担,。泰勒级数是用多项式形式在某些特定点
附近来表示一个复杂函数的数学技术(或者说多项式序列,序列越长,逼近的精度越
高)。在我们所应用的场合,我们在r-O附近杷畸变函数展开为多项式形式、这个多
项式的通用形式是J:r)=ao +a,r+口2r 2+在这里,当r-O时,只r)=O.这意
味着ao-O,因为函数必须是关于r径向对称,所以,只有r的偶次琴项不为0。因
摄像机模型与标定4
望
镜头
第21页
OCR文字识别结果:
三
为kl,而第二项为k2。对畸变很大的摄像机,比如鱼眼透镜,我们可以使用第三
径向畸变项k3。通常,成像仪某点的径向位置按下式进行调节
yoon. -y(1 + k, r 2 + k 4 + k3'6)
这里(x,y)是畸变点在成像仪上的原始位置,(Xcorrected,y.....Ted)是校正后的新位置。
图11-4显示矩形网格因径向畸变而产生的位移。从前面看,光心越向外,矩形网
格上的点位移越大。
50
100
160
200
2SO
300
350
400
46D
0100 200 300 400 5DD 600
Pixel error = P. 1174. 0. 1159]
Focal Length = (B57. 057. 744) ◆/ · P. 2840, 0. 2894】
Principal Point-02. 717. 242 ◆ j. P. 5912, O. 5571]
Skew = 0. 0004198 ◆不 0. 0001905
R · dlal coe《i cients = (0. 2635. 0. 11e7. 0) ◆/ · P. 00231, D. 009418. 0】
T · ngentlal coeffi olents = 60. 0002789. 6. 174*405) ◆/ · P. 0001217. 0. 0001208]
图1 1 -4某个摄像机透镜的镜像畸变图,箭头显示径向畸变图像上外部矩形网
格的偏移(经Jean-Yves Bouguet授权)
第二大常用畸变是切向畸变。这种畸变是由于透镜制造上的缺陷使得透镜本身与图
像平面不平行而产生的。参见图11-5。【375~376】
切向畸变可以用两个额外参数p,和p2来描述,如下®
这些公式的推导超出本书的范围。一有兴趣的读者可以本考。t锤。模型,死D.C.
Brown br,"Decentering Distortion of Lenses", Photometric Engineering 32 (3) (]966),
444-462.
'.. :
籀勇
412第11章
第22页
OCR文字识别结果:
普通摄像机
图11-5当透镜不完全平行于图像平面的时候产生切向畸变,这种现象发生于
成像仪被粘贴在摄像机的时候(经Sebastian Thrun授权)
因此总共有五个我们所需要的畸变参数。由于在OpencV程序中五个参数都是必
需的,所以它们被放置到一个畸变向量中,这是一个5 × 1的矩阵,按顺序依次包
含kr,k2,pl,p2和k3。图11-6给出了切向畸变在前面外部矩形网格点的影响。这些
点明显在位置和半径上有位移。
Tangential Component of the Distortion Model
100
150
200
250
300
350
400
q{SO
0100 20D 300 400 500 BDO
Pixel ef¢or-P. 1174, 0. 1159]
Focal Length = 065?. 303. 067. 744) ◆/ · P. 2840, 0_2804]
Principal Point = (302.?17, 242. 334) ◆二 P. 5012. 0. SS?1]
Skew-0. 0004198 ◆乒 0. 0001905
Radi al coe«i cients-(-0. 2535. 0. 4187, 0) +/-P, 00231. 0, 0 日 941e, Ol
T angenti al coefficients-(-0. 0002789. 5, 174e · 005) ◆ A P. 0001217, 0. 0001208}
图11-6某摄像机透镜的切向畸变图,箭头显示·切向畸变图像上外部矩形网格
◆
的偏移(经Jean-Yves Bouguet授权)
第23页
OCR文字识别结果:
在图像系统中还有许多其他类型的畸变,不过都没有径向和切向畸变显著。因此不
论我们,还是OpencV,都不打算处理它们。【376~377】
标定
现在,我们已经在数学意义上对摄像机内参数和畸变特性有了一些概念。接下来一
个很自然的问题是,如何利用OpencV来计算内参数矩阵和畸变向量®。
OpencV提供了好几种算法来计算摄像机的内参数。实际的标定是通过
cvcalibratecamera2 0完成的。在这个程序中,标定方法是把摄像机对准一个有
很多独立可标识点的物体。通过在不同角度观看这个物体,可以利用通过每个图像
计算摄像机的相对位置和方向以及摄像机的内参数(见图11-9)。为了提供不同视
角,我们旋转和移动物体。这样,让我们先中断一下,先来学点旋转与平移的
知识。【378】
旋转矩阵与平移向量
对每一幅摄像机得到的特定物体的图像,我们可以在摄像机坐标系统上用旋转和平
移来描述物体的相对位置,见图11-7.
通常,任何维的旋转可以表述为坐标向量与合适尺寸的方阵的乘积。最终一个旋转
等价于在另一个不同坐标系下对点位置的重新表述。坐标系旋转角度e则等同于
将目标点围绕坐标原点反方向旋转同样的角度O。图11-8显示用矩阵乘法对二维
旋转的描述。在三维空间中,旋转可以分解为绕各自坐标轴的二维旋转,其中旋转
轴线的度量保持不变。如果依次绕x,夕和z轴旋转角度!v,俨和俨,那么总的旋转
矩阵R是三个矩阵R.(v),R,(伊)和R,(e)的乘积,其中
国关于摄W机标定的一个优秀网上教程,请见儿an-Yves Bouguet的标定网站
lhttp : //www. vision. caltech. edu/bouguetj/catib_doc).
圆需要清楚一点,这里所描述的旋转是先绕2轴,然后在新&置绕y轴,最后再绕x轴
旋转。
第24页
OCR文字识别结果:
cos O sin Q O
R. (Q)-sin Q cos Q O
0 0
图11-7从物体到摄像机坐标系统的变换物体上的点P对应图像平面上的
点p.点p通过旋转矩阵R和平移向量t的应用与点P相连
图11-8把点旋转e(这里是绕Z轴)等价于坐标轴反向旋转e。通过简单的三
角计算,我们可以看出旋转如何改变点的坐标
因此R=R,(0),R.(〈o),尺,.(v)。旋转矩阵R的特性是它的逆阵就是它的转置阵(我们只
摄像机模型与标定415
让匡
物体坐标
第25页
OCR文字识别结果:
需转回来)。因此有RTR=RXP-I,其中1是对角元素为1,其余为0的单位矩阵。
平移向量用来表示怎样将一个坐标系的原点移动到另一个坐标系的原点,或者说,
平移向量是第一个坐标是原点与第二个坐标系原点的偏移量。因此,从以目标中心
为原点的坐标系移动到以摄像机中心为原点的另一个坐标系,相应的平移向量为
斗目标原点一摄像机原点。那么有图11-7,点在世界坐标系中的坐标P.到在摄像
机坐标系中的坐标P.
P. = R(P.-T) [379-380]
结合上面计算P.的公式以及摄像机内参数校正,我们构造出OpencV所能解决的
基本方程式。这些方程的解将是我们所寻找的摄像机标定参数。
我们已经看到可以用三个角度来表示三维旋转,用三个参数(x,只z)来表示三维平
移。因此我们总共有6个参数。对摄像机而言,OpencV内参数矩阵有4个参数仉,
f。,c.和c,),因此对每个视场的解需要10个参数(注意,摄像机内参数在不同视场
保持不变)。使用一个平面物体,我们很快可以看到每个视场固定8个参数。因为
不同视角下旋转和平移的6个参数会变化,对每一个视角用来求解摄像机内参数矩
阵的两个额外参数需要约束。因此求解全部几何参数至少需要两个视角。
本章稍后将进一步讨论这些参数和相关约束。但首先需要讨论标定物(calibration
object)。OpencV所使用的标定物是一个用不同黑白方块构成的平面格子,通常称
为。棋盘。(即使它没有8个方块,至每个方向的方块个数不相等)。
棋盘
原理上,任何合适的表征物体都可以用作标定物体,而实际上都选用诸如棋盘这样
的规则模式®[174】。文献中一些标定方法是基于三维物体的(如有标记点的盒
子),但是平面棋盘模式更容易处理,因为精确的三维标定物体难以制作(存储和发
布)。因此OpencV不是使用基于3D构造物体的I见场,而是使用平面物体(如棋盘)
的多个视场。我们使用黑白方块交替排列的模式I见图11-9),这保证在测量上任何
一边都没有偏移。而且,格线角点也让亚像素定位函数(在第10章讨论)的使用更
为自然。
给定一个棋盘图像(或者一个人手持棋盘,或任何包含棋盘的视场以及没有任何千
®标定物的具体使用以及更多的标定方法来自Zhang [Zhang99:Zhang00]和Sturm
[Sturm99].
416第11章
第26页
OCR文字识别结果:
■
:背景),可以使用Op.CV函数··indch..h..Rdc...0来定位棋盘的
int cvFindchessboardcorners(
const. Id · image,
cvsize pattern_
pattern_size,
1nt* corner_count NULL,
int flags CV_CALIB_CB_ADAPTIVE_THRESH
国实际使用中,使用棋盘格为不对称的偶奇维数更方便——比如(5,6)。这样的偶一奇不
对你模式使得棋盘只有一个对称轴,从而棋盘的方向总是能惟ー确定。
合实际上,要求会更加严格一些:不仅所有的角点必须被找到,而且必须按照期望的按
行和列排列。只有找到角点而且正确排列,函数才正确返回非0值。
摄像机模型与标定417
臣
第27页
OCR文字识别结果:
之,返回0。最后的flag变量可以用来定义额外的滤波步长以有助于寻找棋1,::
点。所有变量都可以单独或者以逻辑或的方式组合使用。
CV_CALIB_CB_ADAPTIVE_THRESH cvFindchessboardcorners O 的 r ;'
认方式是,首先根据平均亮度对图像进行二值化,但如果设置此标志,则使川
自适应二值化法。【38"3
CV_CALIB_CB_NORMALIZE_IMAGE如果设置该标志,则会在二值化,
前应用函数cvEqualize His仁O来归一化图像。
CV_CALIB_CB_FILTER_QUADS旦二值化图像以后,算法试图根据栱I
上黑色方块的投影视场中定位四边形。这是一个逼近的过程,因为四边形的与
个边都被假设为直的,而实际上由于图像的径向畸变,这个不完全成立。如'.:一
这个标志被设置,那么将使用对这些四边形使用其他额外的约束以拒绝错误rT
四边形,
亚像素角点
cvF1ndchessboardcorners O返回的角点仅仅是近似值。这意味着实际上位置午
精度受限于图像设备的精度,即小于一个像素。必须单独使用另外的函数来计算{i
点的精确位置(用近似位置和图像作为输入)以达到亚像素精度。这个函数与在第10
章中所使用的用于跟踪的cvFindcornersubpixo一样。在本节中使用该函数并·f
奇怪,因为棋盘内角点只是更通用的Harris角点的一种简单形式。之所以使用淇
盘角点仅仅是因为这样做是寻找和跟踪的特别简单方式。如果在第一次定位角点对
忽略调用此亚像素精度函数,那么会导致标定的实际错误。
绘制棋盘角点
尤其是在调试程序时,需要在图像上绘制找到的棋盘角点(通常我们用来第一次I一
算角点图像)。这样我们可以看到投影的角点是否与观察的角点匹配。基于这种以
路,OpencV提供了一个方便程序来处理这种常用的需求。函.
cvDrawchessboardcorners o 将 函 数 cvFlndchessboardcorners O 发现的所有"r
点绘制到所提供的图像上。如果没发现所有的角点,那么得到的角点将用红色网叫
绘制。如果所有的角点被找到,那么角点将使用不同颜色绘制(每行使用单J;,;
色),并且把角点以一定顺序用线连接起来。
void cvDrawchessboardcorners(
CvArr* image,
cvsize pattern-size,
118第n章
第28页
OCR文字识别结果:
Cvpoint2D32f* corners,
int count,
int pat tern-was-found
cvDrawchessboaracorne·so的第一个参数是欲绘制的图像。因为角点是以颜色
圆圈表示的,该图像必须是8位的彩色图像。在大多数场合下,它是
像). [383]
接下来的两个参数pattern_size和corners,与cvFin己chessbo己rdcornerso
中的定义一样。参数count是一个等于角点数目的整数,最后的参数
patternas_foun己表示是否所有的棋盘模式都被成功找到。这可以设置为
cvFin己Chessbo己r己cornerso的返回值。图11-10显示了在棋盘图像上应用函数
cvDrawchessbo己r己Corners O所得到的结果。
图11-10函数cvDrawchessboardcorners0的结果,一旦用函数cvFind一
Chessboardcornerso找到角点,便可以将在找到的角点位置(在角点上的小圆
圈)以及按顺序(用圆圈之间的线来表示)作投影
现在开始讨论平面物体能够做些什么。当通过针孔和透镜时,平面上的点集是经过
透视变换的。该变换的各种参数将被存储到3×3单应性矩阵中,即我们将要讨论
的内容。
单应性
在计算机视觉中,平面的单应性被定义为从一个平面到另一个平面的投影映
摄像机模型与标定419
第29页
OCR文字识别结果:
射m。因此一个二维平面上的点映射到摄像机成像仪上的映射就是平面单应性的例
子。如果对点9到成像仪上的点q的映射使用齐次坐标,这种映射可以用矩阵相
乘的方式表示。若有以下定义
则可以将单应性简单表示为
= sHg
这里引人参数s,它是一个任意尺度比例(目的是使得单应性被定义到该尺度比
例)。通常根据习惯放在H的外面。
稍微利用一点几何和矩阵代数的知识,便可以求解这个变换矩阵。最重要的是H
有两部分用于定位观察的物体平面的物理变换和使用摄像机内参数矩阵的投影。
参见图11-11.
图1 1-11用单应性来描述平面物体的观测从物体平面到图像平面的映射,
同时表征了这个两个平面的相对位置和摄像机投影矩阵【384-385】
®术语。单应性。在不同学科上有各种不同的含义。例如,在数学上,它有更通用的意
思。计算机视觉中,对单应性最感兴趣的部分只是其他意义中的一个子集。
420第11章
第30页
OCR文字识别结果:
昏一一一.门封封
物理变换部分是与观测到的图像平面相关的部分旋转R和部分平移t的影响之和。
因为使用齐次坐标,我们可以把它们组合到一个单一矩阵中,如下所示©
W-[R t]
然后,通过乘以嗵,得到摄像机矩阵械用来表示影射坐标),即
Fj. O Cx
卜从m冒,其中M一1 o儿c,
0 0
这看起来已经完成了。但实际上,我们的关注点不是表征所有空间的坐标Q,而只
是定义我们所寻找的平面的坐标Q'。这需要简化。
考虑到一般性,我们可以选择'定义这个物体平面,使得Z=0。这样做的原因是如果
把旋转矩阵也分解为3个3 × 1向量(即R=卜1 r2 r3],那么其中的一个列向量就不
映射目标点到成像仪的单应性矩阵H可以完全用H=s州rl r2 t]表述,,其中
q = sHg(
注意,H现在是3 ×3矩阵。
OpencV使用上述公式来计算单应性矩阵。它使用同一物体的多个图像来计算每
个视场的旋转和平移,同时也计算摄像机的内参数(对所有视场不变)。如我们所讨
论的,旋转和平移分别用三个角度和三个偏移量定义,因此对每个视场,有6个未
知量。这没有问题,因为一个已知平面物体(如棋盘)能够提供8个方程,即映射一
个正方形到四边形可以用4个(x,y)点来描述。每个新的图像帧为计算新的6个未
知量提供8个方程,因此若给定足够图像,我们能够计算出未知内参数的任何值
(或者更多)。【386】
通过下面的简单方程,单应性矩阵H把源图像平面上的点集位置与目标图像平面
国这里W =[R t]是一个3 ×4矩阵、前三列包含尺的9个元素,最后一列由拥有三个元素
的向量t组成。
摄像机模型与标定421
I &
第31页
OCR文字识别结果:
(通常为成像仪平面)上的点集注
:置联系起来
OpencV提供了一个方便的函数cvFin己Homography O,以对应点序列作为输人,
返回最佳描述这些对应点的单应性矩阵。我们最少需要4个点来求解H,但是如果
有,通常提供更多的点"(如我们提供的大于3 × 3的棋盘)。使用更多点的好处是尽
可能减少噪声和其他不确定因素所带来的干扰。
void cvFindHomography(
const CvMat"src_points,
const CvMat · dst_points,
CvMat"homography
输入数组src_points和dst_points即可以是JV×2,也可以是JV×3矩阵。对于
前者,点是以像素坐标表示,对于后者,希望是齐次坐标。最后的变量
变量
homography,其值为函数所填写的3 × 3矩阵,以保证反向投影误差最小。因为在
单应性矩阵中只有8个独立参数,我们选择归一化,使得H33-1。但通常的方法是
对整个单应性矩阵乘以一个尺度比例。
装
摄像机标定
最后我们为摄像机内参数和畸变参数进行摄像机标定。在本节中,我们首先学习使
用cvcalibratecamera2 o来计算这些值,并且利用这些模型对来自标定摄像机的
图像畸变进行矫正。首先讨论需要多少棋盘视场图像来求解内参数和畸变。然后在
转到简化此工作的代码之前,概述OpencV是如何求解这个系统的。【387】
®自然,要保证精确解我们只需要4个对应点。如果提供更多,我们的计算结果便是最
小二乘误差意义上的最优解。
422第11章
第32页
OCR文字识别结果:
w ;
首先回顾我们的未知因素,即标定过程求解究竟需要多少参数?在OpencV里,
我们有4个内参数仉,如c.,c,)和5个畸变参数——三个径向(k,,k2,k3)和两个切向
中:,p2)。内参数直接与棋盘所在空间的3D几何相关(即外参数),而畸变参数则与
点集如何畸变的2D集合相关。因此我们要分别处理两大类参数。为求解5个畸变
参数(为了增加鲁棒性自然也可以有更多参数),需要已知模式的三个角点所产生的
6组信息(在理论上)是所有需要解决的5个畸变参数(当然,可以利用更多的参数以
达到鲁棒性)。因此,在内参数计算中,可以利用一个棋盘视场,接下来考虑外参
数。对外参数,我们需要知道棋盘的位置。对棋盘的6个不同视场图像,需要三个
旋转参数(叭叭O)和三个平移参数(T.写T-,因为在每幅中棋盘是移动的。总而言
之,在每个视场中,我们必须计算4个内参数和6个外参数。
假设有N个角点和K个棋盘图像(不同位置),需要多少视场图像和角点才能提供足
够的约束来求解所有这些参数?
K个棋盘图形提供2NK个约束(乘以2是因为每个点都由x和y两个坐标值组
成的)。
忽略每次的畸变参数,我们有4个内参数和6K个外参数(因为我们需要在每K
个视场中的找到棋盘位置的6个参数)
有解的前提是2LVK弘6K +4成立(或者等价地,(N-3)K加2)
似乎当犀-5且K=l时成立。且慢,对于我们,K(图像个数)必须大于1。要求K》l
是因为我们使用棋盘来为适合每个视场图像的单应性矩阵标定。如前面所讨论的,
一个单应性矩阵可以从4组(x,夕)坐标对中产生多达8个参数。这是因为为了表示平
面投影视场的所有目标只需要4个点即一次性在四个方向伸展正方形的边,把它
变成任意四边形(见第6章的投影图像)。因此无论在一个平面上检测到多少个角
点,我们只能得到四个有用的角点信息。鉴于每个棋盘视场,方程只能给我fr_I四个
角点信息或者(4-3)K〉l,即K〉l。这意味着一个3 × 3棋盘(只计算内部角点)最少
需要两个视场来求解标定问题。考虑到噪声和数值稳定性要求,对大棋盘需要收集
更多的图像。实际使用中,为了得到高质量结果,至少需要10幅7× 8或者更大棋
盘的图像(而且只在移动棋盘在不同图像中足够大以从视场图像中得到更加丰富的
信,.). [388]
内幕探秘
本小节是为求知欲旺盛的人准备的。如果你只想调用标定函数,完全可以略过不
摄像机模型与标定423
第33页
OCR文字识别结果:
读。如果想继续跟随我们的脚步,就会想到这个问题数学是怎么应用于标定的?
尽管有很多求解摄像机参数的方法,OpencV选择那些能够很好工作于平面物体的
方法。OpencV中使用的求解焦距和偏移的算法是基于zhangj张)的方法
[Zhang00],但求解畸变参数则是另外的基于Brown [Brown71]的方法。
首先,我们假定在求解标定参数时摄像机没有畸变。对每一个棋盘视场,我们得到
一个前面描述的单应性矩阵H.将H转写为列向量形式,H=【h,h,h3],每个h
是3 × 1向量。则通过前面对单应性矩阵的讨论,我们可以设置H等于摄像机内参
数矩阵M乘以前两个旋转矩阵rl和r2与平移向量t的组合矩阵,再加上缩放因子
s,即有
H = [ A A] = sMh fz t]
分解方程,得到
八一s鹏或r,一又M-'私
队一SMfr或「飞一又M-'h,
队一sMt或t一又M-'曳
这里又一1/s.
旋转向量在构造中是相互正交的,将缩放因子提到外面,则有Tr和r2相互正交。
正交有两个含义旋转向量的点积为0,而且向量的长度相等。从点积开始,我
们有
_T fz · O
对任何向量a和b,我们有(ab)T_br.T,因此替换引和r2,得到第一个约束
h'M-T M''= O
其中A-T是(A-「)T的简写形式,已知旋转向量的长度相等
代替rl和r2,我们得到第二个约束
h'M-'M''= K M-'M-'h,
为了使事情更容易些,设置B=勣"T甘',展开有【389】
莘勇
424第11章
第34页
OCR文字识别结果:
事实上,矩阵B有通用形式的封闭解
使用B矩阵,两个约束有其通用的形式肾B乜。将矩阵乘开看看每个元素的形式。
因为B是对称的,它可以为写成6个元素向量的点积。重新排列B的元素得到一
个新的向量b,我们有
使用v的定义,两个约束可以写为
(v.. v.. f b = 0
如果我们同时得到K个棋盘图像,堆叠这些方程,有
Vb = O
其中r是2K ×6的矩阵。如前所述,如果K加2,那么方程有解b=[B11,B山B22,
B山B23,B33] T.摄像机内参数可以从B矩阵的封闭解中直接得到
ff.-= )l/ B..
f. = J JLB.. I(B.. Bzz-Bn
=一B、严1丸
其中
第35页
OCR文字识别结果:
A-B..-[B + c. (B,zB,3-BHB.)VB..
1单应性条件计算得到
外参数(旋转和平移)可以由单应性条件计算得到
. AM-'
f3 · r, Xfz
t = AM''\
这里比例比例由正交条件确定兄=川I M-乓II.
需要小心的是,当我们使用真实数据求解时,将r向量放置在一起(R=fri r2
r3]),我们无法得到一个精确的旋转矩阵,即RTR=RRR_I成立。
要解决这个问题,常用的技巧是使用R的奇异值分解(SVD)。如第3章所讨论的,
SVD是将矩阵分解为一个对角阵D和两个正交阵口和V的数学方法。这允许我们
将R转化为R=mv「。因为R本身是正交的,矩阵D必须是单位阵I,使得
以【V「。我们可以通过对R的奇异值分解,设置D为单位阵,用SVD方法再重新合
成R,将R强制计算为吻合的旋转矩阵R'。
除了所有的这些工作,我们还没有处理透镜畸变。我们是用前面得到摄像机内参
数——连同畸变参数都设置为O一作为我们的初始值,然后来求解大的系统方程。
由于畸变而在图像上得到的感知点的位置是不真实的。如果针孔模型是完美的,令
(xp,}p)为点的位置,令(x山只1)为畸变位置,那么有
Lyp]-Lf, X ° / Z °.., J
通过下面的替换,可以得到没有畸变的标定结果【390~391】
这样在重新估计内外参数后,我们得到的这些大量方程可以找到畸变参数。这对单
个函数cvcalibratecamera20®而言是一个繁重的工作。
cvca1 ibratecamera2 0为第12章中的立体标定函数内部所使用。对立体标定,我
有1需要在同一时间内标定两个摄像机,并且希望将它们通过一个旋转矩阵和平移向量
联系到一起。
第36页
OCR文字识别结果:
标定函数
一旦我们有多个图像的角点,就可以调用函数cvcalibratecamera2 0。此函数将
要做大量分解工作以提供我们所需的信息。具体来说,我们会得到摄像机内参数矩
阵、畸变系数、旋转向量和平移向量。前两个构成摄像机的内参数,后两个构成了
物体(如棋盘)位置和方向的摄像机外参数。畸变系数(k,,k2,pl:p2和k,)。【181】来自
于我们前面遇到的径向和切向畸变方程。它们有助于矫正这些畸变。摄像机内参数
矩阵也许是最有用的结果,因为它可以让我们将3D坐标转换为2D图像坐标。我
们也可以使用摄像机矩阵来做相反操作,但这种时候,我们只能得到与图像点对应
的三维世界中的一条线。回头再讨论。
让我们检査一下摄像机标定程序本身。
void cvcalibratecamera2(
CvMat · obj ect-points,
CvMat * image-points,
int · point-count s.
cvsize image-size,
CvMat* intrinsic-matrix,
CvMat* distortion-coeffs,
CvMat · rotat ion-vectors =. NULL,
CvMat* translation-vectors = NULL,
int flags-O
调用cvcalibratecamera2 0时,虽然很多变量的本身意思清晰,但我们还是尽量
阐述它们,以期能被准确理解。【392】
第一个参数object_points是一个N×3矩阵,包含物体的每k个点在每M个图
像上的物理坐标(即犀-Kx间。这些点位于物体的坐标平面上®。该变量实际上比
看起来的更微妙一些,这在与我们描述物体上的点的方式隐含着坐标系统的结构和
物理单位都已经被事先定义。1列如,在使用棋盘的场合,我们定义了坐标系使得所
有棋盘上的点的z坐标值为O,而x和y坐标用厘米度量。如果选用英寸,所有参
®第二个径向畸变参数k3最后出现是因为它是OpencV后加的一个条件、用于更好地矫
正因鱼眼透镜而产生的畸变。我们即刻看到k3的初始值可以设置为O,然后设置标志
位为CV_CALIB_FIX_K3.
圆当然,在不同图像中使用同一个物体很正常,所以厅个点实际上是同一个物体的K个
点的M次重复列表。
摄像机模型与标定427
i医
第37页
OCR文字识别结果:
数的计算结果也是用英寸表示。类似地,如果设置所有x坐标值,:;.,..,、:':::,
0,那么意味着与摄像机相关的棋盘位置将主要在X方向上而不是卜丁,;...j·.,,,.,
方形定义了一个单位,即如果正方形的边长是90mm,那么在摄像机世界,-、4杠子
和摄像机坐标单位应该是mm/90。理论上,可以使用棋盘以外的f;。:弦;;、I ii.
因此所有物体上的点不必一定在一个平面上。但是使用平面更容易乜i:,.;I"佷pj
最简单的方式是,我们简单定义棋盘的每个方块为一个单位,这样供。,,卜,,匀卜·云
横竖排列都是整数。定义S...,,为棋盘宽度方向的方块个数表示宽度,"t.",,.,,;.:;一
高度方向的方块个数表示高度
第二个变量是image_poin亡s,它是一个N×2矩阵,包含object一户.,,上·;山过'ii
的所有点的像素坐标。如果使用棋盘进行标定,那么这个变量简单地山.,I'll}小
cvFin己chessboar己corne·s0的返回值构成。但是现在它被以另外····,.::fi·!。.-
的格式重新排列。
变量point_counts表示每个图像的点的个数,以Mxl矩阵形:八,提:l,:,
Image_size是以像素衡量的图像尺寸,图像点就是从该图像中提取(例如自仁揺义
的棋盘图像)。
下面两个变量intrinsic_matrix和己istortion_coeffs构成了摄像杉I,:,向内巷
数。这些变量既可以是输出参数(标定的主要原因就是填充它们)也司LA是输八荟。
数。当被用作输入参数,函数调用时这些矩阵的数值将会影响计算结果,面层弓:f)叮
当作输入参数使用则由后面的标志位参数决定,见随后的讨论。如前面芦!ri·八权,\、
参数矩阵完全定义了理想摄像机模型的摄像机行为,而畸变系数则更多表汨,博象机
的非理想行为。摄像机矩阵总是3×3的,而畸变系数总是5个。所以dj吕l门rl.I.n一
coeffs变量是一个指向5×l矩阵的指针(记录1顺序是k,,kz,p】,p2,k3)。「3".{-3o-\l
鉴于前两个变量概括的是摄像机的内参数信息,接下来的两个变量将概况I·;芸奻信
息。也就是,它们说明与在每幅图像中相对于摄像机来说的标定物体(即棋撤)的(立
置。物体位置由旋转和平移表征®。旋转rotation_vectors由M个丁.'..,;"」.i爿
列为M× 3的矩阵(M即为图像个数)。需要小心的是,这些向量不是孜f:,i!;;」iti;,山。
国行文至此,在运行最优化算法之前,平面的标定物体需要对内参数进行向·,,,.;,
这意味着如果你有一个非平面模板,必须为主点和焦距提供初始的猜测温(毛兀自1丁
论 的 CV_CALIB_USE_INTRINSIC_GUESS).
园可以想像,棋盘位置被描述为(1)在摄像机坐标原点创建一个棋盘t山i卜·;t'.3崔:T
某个轴旋转棋盘(3)将旋转的棋盘移到某个特定位置。这些类似Oper,山,.,J!栄V上
家应该不会陌生。
42B第\\章
第38页
OCR文字识别结果:
论的3×3旋转矩阵,而是代表棋盘围绕摄像机坐标系统下三维空间的坐标轴的旋
转,其中每个向量的长度表示逆时针旋转的角度。每个旋转向量可以通过调用
cvRodrigues2o转换为3 × 3的旋转矩阵,这将在后文讨论。平移
translation_vect·rs则简单排列为第二个M× 3矩阵,同样是在摄像机坐标系
下。如前所述,摄像机坐标系的单位以棋盘的方块单位为准,即如果棋盘方块边长
为1英寸,那么单位就是英寸。
通过优化方法找到这些参数是一个富有技巧性的工作。如果设置的初始值位置远离
实际解,有时试图一次性求解所有参数会导致结果不精确或者不收敛。因此,通常
需要猜测解以得到更好的初始值。因此,我们常常固定某些参数而求解另外一些参
数,然后再固定另外的参数求解原始的固定参数,依次往复,最后可以认为所有参
数都接近真实解,然后使用所有的参数作为初始值一次性输入。OpencV允许你控
制所有的标志位。标志位变量是用来做某些细微的控制使得标定能够完成的更好。
如有必要,下面的值可以综合使用逻辑运算。或。。
CV_CALIB_USE_INTRINSIC_GUESS cvcalibratecamera2 0 计 算 内 参 数
矩阵的时候通常不需要额外信息。具体说来,参数c.和c,(图像中心)的初始值
可以直接从变量image_size中得到。如果设置该变量,那么intrinsic_matrix
假设包含正确值,并被用作初始猜测,为cvcalibratecam导ra2 0做优化时
所用。【394】
,CV_CALIB_FIX_PRINCIPAL_POINT这个标志既可以与cv_CALIB_usE一
INTRINSIc_GuESs一起使用,也可以单独使用。如果单独使用,则设置图像中心
为主点。如果一起使用,则设置主点位置为intrinsic_matrix提供的初始值。
CV_CALIB_FIX_ASPECT_RATIO如果设置该标志,那么在调用标定程序
时,优化过程只同时改变f、和f,,而固定intrinsic_matrix的其他值(如果
CV_CALIB一USE_INTRINSIC_GUESS也没有被设置,则intrinsic_matrix中
的f、和f,可以为任何值,但比例相关。
CV_CALIB_FIX_FOCAL_LENGTH该标志在优化时候,直接使用
Intrinsic_matrix中传递过来的f,和f,值。
CV_CALIB_FIX_KI, CV_CALIB_FIX_K2 and CV_CALI B_FIX_K3 固 定 径
向畸变k\,k2和k3。径向畸变参数可以通过组合这些标志设置为任意值。一般
地,最后一个参数应设置为O,除非使用鱼眼透镜。
'真,因为精确制作导致很小的切向畸变。试图将参数拟合0会导致噪声干扰
摄像机模型与标定429
第39页
OCR文字识别结果:
和数值不稳定。通过设置该标志可以切向畸变参数pr和p2的拟合,即设置两
个参数为0.
只计算外参数
某些情况下我们已经得到了摄像机的内参数,因此只需要计算观察物体的位置。这
种场景与一般的摄像机标定明显不同,但是也是一项值得完成的有用工作。
void cvFindExtrinsiccameraparams2(
const CvMat* obj ect_points,
const CvMat* image_points,
const CvMat* intrinsic_matrix,
const CvMat* distortion_coeffs,
CvMat* rotation_vector,
CvMat* translation_vector
cvFin己Extrinsiccameraparams2 0的变量与cvcalibratecamera2 0的相应变量
相同,只是内参数矩阵和畸变系数是直接提供而非计算出来的。旋转输出的格式是
1× 3或3 × 1旋转向量,表示棋盘或者点绕坐标轴的旋转,而向量长度则表示逆时
针的旋转角度。这个旋转向量可以通过cvRodrigues2o转换为3×3矩阵,如前
面所讨论的。平移向量是摄像机坐标系中棋盘原点的偏移量。【395-396】
矫正
如我们已经提过的,标定摄像机通常是想做两件事,一个是矫正畸变效应,另一个
是根据获得的图像重构三维场景。在深入第12章讨论第二个复杂任务之前,我们
先花点时间考虑第一个任务。
OpencV提供一个直接使用的校正算法,即输入原始图像和由函数
cvcalibratecamera2 0得到的畸变系数,生成矫正后的图像(见图11-12)。我f门既
可以一次性通过函数cvundistort20使用该算法完成所有事项,也可以通过一对
函数cvlnitun己istortMapo和cvRemapo来更有效率的处理此事,这通常适合视
频或者从同一摄像机中得到多个图像的应用玺。
®我们花点功夫清晰区分一下。矫正。(undisto八ion)与。校正。(rectification)的关系
"矫正。是在数学上去掉透镜峙变,而。校正。是数学上将图像排列整齐。
430第11章
第40页
OCR文字识别结果:
基本方法是先计算畸变映射,再矫正图像。函数cvlnitundistort Mapo用于计算
畸变映射,而函数cvRemap O表示在任意图像应用该映射。。函数cvundis七ort2 0
是在一次调用中先后完成两个步骤。但是计算畸变映射是一个耗时的操作,所以,
当畸变映射不变的时候随时调用函数cvundistort20是一种不聪明的做法。最
后,如果有一系列的2D点,我们可以调用函数cvundis亡ortpoin七so从原始坐
标变换到矫正后的坐标。【396】
/ / Undistort images
void cvlnitundistort Map(
const CvMat · intrinsic_matrix,
const CvMat · distortion_coeffs,
cvArr* mapx,
cvArr* mapy
void cvundistort2(
const CvArr* src,
CvArr* dst,
const cvMat* intrinsi. c-matrix,
const cvMat* distortion-coef £s
/ / Undistort a list o£ 2D points only
void cvundistortpoints(
const CvMat* src,
CvMat · dst,
const CvMat* intrinsic-matrix,
const CvMat* distortion-coe££s,
国我们最先在图像变换(第6章)的上下文中遇到cvRemapo。
摄像机模型与标定431
1.
■
第41页
OCR文字识别结果:
const CvMat* R O,
const CvMat* Mr O
函数cvlnitun己istort Mapo计算畸变映射,该映射将图像中的每个点与其映射位
置关联。前两个变量是摄像机内参数矩阵和畸变系数,全部是来自函数
cvcalibratecamera2(·)的期望形式。生成的畸变映射由两个单独的32位单通道
矩阵所表示第一个给出点被映射的x值,第二个给出7值。你可能会疑惑,为何
不直接用一个双通道数组代替。因为来自cvunitun己istort Map O的结果可以直接
传递给函数cvRemapo。
函数cvun己istort2o一次完成所有事情。它输入初始量(畸变图像)以及摄像机内
参数矩阵和畸变系数,输出同样尺寸的矫正图像。如前所述,如果你有一系列来自
原始图像的2维点坐标并且计算相应的矫正点坐标,那么使用
cvundistortpoints o。它有两个额外的参数与使用在第12章讨论的立体校正中
相关。这些参数是R,两个摄像机之间的旋转矩阵,和林矫正后摄像机的内参数
矩阵(在第12章中仅仅当有两个摄像机时被使用)。矫正后的摄像机矩阵M,可以是
3×3矩阵或者3×4矩阵,即分别是从cvstereo Rectifyo返回的摄像机矩阵P,
和P2(有关左或右摄像机,参见第12章)的数值中得到的前3列或者整个4列。这
些参数的默认值是NuLL,表示函数被解释为单位矩阵。
一次完成标定
好了,现在是时候用例子来把所有东西放在一起了。我们通过程序来完成如下功
能它先寻找用户指定维数的棋盘,然后捕捉到用户需要的许多完整图像(即能找
到棋盘的所有角点),计算摄像机内参数和畸变参数,最后进入显示模式,以显示
矫正后的摄像机图像,见例11-1。当使用这个算法,在连续的捕获之间想要充分
的改变棋盘的视角,否则求解标定参数的点集会是病态矩阵(非满秩),其结果是要
么得到一个坏解,要么干脆无解。【397--398】
例11-1:读入棋盘的宽度和高度,读入收集到的不同场景图像,然后标定摄像机
/ / Calling convention
/ / calib board-w board-h number-of-views
/ / Hit'p'to pause / unpause, ESC to quit
432第11章
第42页
OCR文字识别结果:
。.一菡一。一长戛羹封却
逐一箠
#include <cv. H>
#include <highgui. H>
#include <stdio. H>
#include <stdlib. H>
int n_boards O //will be set by input list
const int board_dt 2D //wait 20 frames per chessboard view
int board_w
int board_h
int main{int arge, char* argv[] )
if ( arge :-4 ) {
printf(" ER.R.OR Wrong number of input parameters\n")
return-1
board-w · atoi ( argv[1] )
board-h. Atoi ( argv[2] )
n-boards = atoi«argv[3] )
int board-n-board-w · boardl-h
Cvsize board-sz = cvsize( board-w, board-h )
Cvcapture * capture = cvcreatecameracapture( 0 )
assert( capture )
cvNamedwindow ('Calibration")
//ALLOCATE STOR. AGE
CvMat* image_points cvcreate Mat ( n_boards · board_n, 2,
CV_32FC1 )
CvMat* object_points cvcreateMat(n_boards · board_n, 3,
CV_32FC1 )
CvMat"point_counts cvcreate Mat ( n_boards, 1, CV_32S01 )
CvMat* intrinsic_matrix cvcreateMat{3, 3, CV_32FC1 )
CvMat · distortion_coeffs = cvcreate Mat(5, 1, CV_32FC1 )
Cvpoint2D32£* corners new Cvpoint2D32£t board-n
int corner count
int successes o
in 匕 step, frame O
Iplimage * image-cvQuery FrELme( ceLpture )
Ipllmage * gray-image-cvcreatelmage{cvGetsize(image, 8, 1 )
/ /subpixel
摄像机模型与标定433
第43页
OCR文字识别结果:
// CApTURE CORNER vIEWS LOOP UNTIL WE'vE GOT n_bords
// SUCCESSFUL CAPTURES ( ALL CORNERS ON THE BOARD ARE FOLJ
while(successes < n_boards )
//skip every board_dt frames to allow usET to move ches. :.- · .-
I f ( frame++ % board_dt-O )
//Find chessboard corners
int found criFindchessboardcorners(
image, board_sz, corners, & corner_count,
CV_CA L I B_CB_ADAPT I VE_THRESH CV_CAL I B_CB_F I LTER_. · ..!.'')'
/ / Get Subpixel accuracy on those corners
cvcvtcolor ( image, gray_image, CV_BGR2GRAY )
cvFindcornersubpix ( gray_iMage, corners, corner_count,
cvsize(11, 11 ), cvs1ze(-1,-1 ), cvTermcriteria(
CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 3 0, 0. 1 ) )
//nraw it
cvDrawchessboardcorners ( image, board_s z, corners,
corner_count, found )
cvshowlmage('Calibration", image
// if we got a good board, a 己巳 it to our data
if ( corner_count board_n )
step successes · board_n
fori int I-step, j = 0 j<board_n ++i, ++j )
CV_MAT_ELEM("image_points, float, I, O ) corne. Rs[J]. x
CV_MAT_ELEM( · Image_points, float, I, 1 ) corners[ j] y
CVLMAT_ELEM ( · object_points, f loat, I, O ) j lboard_w
CV_MAT_ELEM("obj ect_points, float, I, 1 ) j %baard_w
CV_MAT_ELEM("obj ect_points, float, I, 2 ) 0. 0 f
CV_MAT_ELEM("point_counts, int, successes, O ) baard_n
successes++
/ / end skip board-dt between chessboard capture
/ / Handle pause / unclause and ESC
434第11章
第44页
OCR文字识别结果:
.
int c = cvwait Key ( 15 )
if ( c =='p')
C = O
while(c ! · 'p'& & c ! · 27 ) {
c = cvwait Key ( 250 ) 1
if ( c 27 )
return o
image cvQuery Frame( capture / / Get next image
/ lEND COLLECTION WHILE LOOP.
//ALLOCATE MATRICES ACCORDING TO HOW MANy CHESSBOARDS FOUND
CvMat* object_points2 cvcreate Mat[successes*board_n, 3, CV_32FC1 )
CvMat* image_points2 cvcreate Mat(successes*board_n, 2, Cv_32FC1 ) I
CvMat'point_counts2 cvcreate Mat(successes, 1, CV_32s01 )
//TRANSFER THE POINTS INTO THE CORRECT SIZE MATRICES
//Below, we write out the details in the next two loops. We could
//instead have written
/ / image-points->rows = object-points->rows = \
//successes*board-n point-counts->rows = successes
for(int 1-0 i<successes*board-n ++i)
CV-MAT-ELEM( · image-points2, float, I, O ) =
CV-MAT-ELEM ( * image-points. Float, I, O )
CV-MAT-ELEM ( * image-points2, float, I, 1} =
CV-MAT-ELEM ( * image-points, float, I, 1 )
CV-MAT-ELEM ( * obj ect-points2, float, I, O ) =
CV-MAT-ELEM ( *obj ect-points, float, I, O ),
CV-MAT-ELEM( * obj ect-points2, floeLt, I. 1 ) =
CV-MAT-ELEM ( +obj ect-points, floiilt, I, 1 )
CV-MAT-ELEM( *obj ect-points2, floelt, I, 2 ) =
CV-MAT-ELEM( +obj ect-points, float, I, 2 )
for(int I = 0 i<successes ++i) ( //These are all the same number
CV_MAT_ELEM( *point_counts2, int, I, O ) CV_MAT_ELEM(
"point_counts, int, 1, 0 )
cvRelease Mat (&Object_points )
cvRelease Mat ( &image_points )
cvReleaseMat ( &point_counts )
摄像机模型与标定435
第45页
OCR文字识别结果:
// At this point we have all of the chessboard corners we need.
// Initialize the intrinsic matrix such that the two focal
/ / lengths have a ratio of 1. 0
CV-MAT-ELEM( *intrinsic-matrix, float, O, O ) 1. 0f
CV-MA-ELEM( *intrinsic-matrix, float 11 ) 1. 0f
¢ ¢ t
/ / CALIBRATE THE CAMERA
cvcal ibratecamera2 (
obj ect-points2, image-points2,
point-counts 2, cvGet Si z e ( image ),
intrinsic-matrix, di stortion-coe£fs,
NULL, NULL, O / / CV-CALIB-F IX-ASPECT-RATIO
/ /
/ / SAVE THE INTRINSICS AND DISTORTIONS
cvsave ("Intrinsics. xm1", intrinsi c-matrix )
cvsave("Distortion. xm1", distortion-coeffs )
/ / EXAMPLE OF LOADING THESE MATRICES BACK IN
CvMat · intrinsic ( CvMat * ) cvLoad ("Intrinsics. xm1")
CvMat *distortion = ( CvMat* ) cvLoad("Distortion. xm1"
/ / Build the undistort map that we will use for all
// subsequent frames.
Iplimage* mapx cvcreatelmage( cvGetsize ( image ), IPL_DEPTH_32F,
1 )
Iplimage* mapy cvcreatelmage( cvGetsize ( image ), IPL_DEpTH_32F,
1 )
cvlnitundistort Map (
intrins I c,
distortion,
mapx,
mapy
Ih
// Just run the camera to the screen, now showing the raw and
/ / the undistorted image.
cvNamedwindow("Undistort")
whi 1 e ( image )
436第11章
'. :, ; :, ; :. ; a
第46页
OCR文字识别结果:
capture )
, :""."[398-401]
当处理三维空间的时候常常需要用3×3矩阵表征空间旋转。这种表示方法通常
是最方便的,因为一个向量乘以该矩阵等价于该向量某种方式的旋转。不便之处是
它不能直观显示3 × 3矩阵的旋转含义。另外一个容易可视化的表示方式®[187]是
用向量形式表示旋转,而该旋转每次用单个角度来操作。这种情况下,最标准的方
式是仅用一个向量来说明绕坐标轴的旋转,向量长度表示绕轴逆时针旋转的角度。
这个很容易实现,由于方向可以用任意长度的向量表示,因此我们选择向量的长度
表示旋转角度。两种表述方式的关系是矩阵和向量可以用罗德里格斯变换关联》。
设r为三维向量r-[乙「,r。],这个向量含蓄地定义O,旋转量用r的长度表示。我
们能够将这种以坐标轴一标量形式表示的旋转转换为一个旋转矩阵R
"简单。的表示方式对人不合适。三维空间的旋转只有三个变量。对数值优化程序
处理用罗德里格斯表示的三个元素比用3 × 3旋转矩阵的9个元素更有效率。
四罗德里格斯是十九世纪法国数学家。
摄像机模型与标定437
匿匪
// Show raw image
// Undistort image
// Show corrected image
第47页
OCR文字识别结果:
'"os (Q) r+o-cos(oD · rr T +sin (o) L! f I
我们也能反向从坐标轴表现形式得到旋转矩阵
因此我们发现一种表示形式(矩阵表示)更方便地计算,而另一种表现形式(罗德罗.
格斯表示)更易于理解。OpencV为我们提供了相互转换的函数
void cvRodrigues2(
const CvMat · src,
CvMat · dst,
CvMat · jacobian = NULL
假定我们有向量r和对应的旋转矩阵R,设置src为3 × 1向量r,dst为3 × 3旋转
矩阵R.相反,我们可以设置src为3 × 3旋转矩阵R,以及己st为3 × 1向量r.
不论在哪种情况下,函数cvR口drigues2o都会正确执行。最后的参数是可选的。
如果jacobian不为NuLL,那么它应该是一个3×9或9×3矩阵的指针,其元素是
对应输入数组元素的输出数组元素的偏微分。jacobin输出主要用于函数
cvFindExtrinsiccameraparameters20/Fu 函数 cvcalibratecamerazo 的内部
优化算法。函数中jabobian的应用通常会局限于仅仅将
cvFindExtrinsiccameraparameters20 和 cvcalibratecamera20 的输出从罗
德里格斯的1 × 3或3 × 1坐标轴角度向量格式转换为旋转矩阵。如果是这样,请将
jacobian设置为NU乙L.
练习
1.根据图】[-2,利用摄像机中心位置偏移的相似.角形推导方程得出方程
2真实中心位置(c.,c.,)的估计错误是否会影响其他参2l的f.\计,如焦距的估计?
提示参见方程q-MQ.
3分另1」根据以下条件绘制一个正方形的图像
438第11章
第48页
OCR文字识别结果:
厂一淂。一露飚陲如国
a,在径向畸变下,
b,在切向畸变下4
c、在两种畸变下。
4.参考图11-13,对投影变换,对以下问题进行解释。
a。无穷远的线来自何处?
b,为何目标平面的平行线收敛到图像平面的一个点?
C.
假定物体平面和图像平面相互垂直。在物体平面上,从一点pr开始,从图
f象平面开始,远离其10个单位到p2,在图像平面上的相应移动距离是
多少?
图11-13显示物体平面与图像平面相交以及投影中心视场表示的单应性示意图
5,图11-3显示向A·凸出的。筒形畸变。效应,它在图11-12中则更为明显。一
些透镜是否能产生向内弯曲的效果?如何能做到?
6使用一个便宜的网络摄像机或者手机,创建有径向和切向!畸变的I司心正方形或
棋盘图像。
7在练习6中标定摄像村L.显示矫正前后的图像。
8通过收集棋盘的多幅图像以及对所有图像进行恰当的标定、做数值稳定性和噪
声实验。然后,当,荻少棋盘图像数量时,看看校准参数是怎样变化的将€I果
摄像机模型与标定439
第49页
OCR文字识别结果:
用图表的形式表示出来摄像机参数作为棋盘图像数量的一个函数。
9参考练习8,当使用10幅大小为3×5,4×6和5×7的棋盘时,标定参数怎
样变化?将结果用图表的形式表示出来。
10.高端摄像机显然有可以物理矫正图像畸变的透镜系统。如果你强行对该摄像机
使用多项矫正模型会发生什么现象?
提示此条件被称为过拟合。
11.
三维游戏杆策略。使用视频,摇晃棋盘并使用cvFindExtrinsiccamera一
params2o作为三维游戏杆,来标定一个摄像机。记住
cvFindExtrinsiccamerapar己ms20输出3 × 1或l× 3的旋转向量和三维平移
向量,其中旋转向量长度表示沿着3D变换向量的方向而逆时针的旋转角度。
a,输出棋盘的坐标轴和当移动棋盘时真实世界的旋转角度。处理棋盘不在视
场中的情况。
b.
使用函数cvRodrigues2 0将cvFindExtrinsiccameraparams2 0的输出
转换为3 × 3的旋转矩阵和平移向量。并利用它动态模拟一个飞机被实时渲
染到图像上的简单三维棒图,如同在视频摄像机的视场中移动棋盘一样。
4-40第11章