《Learning OpenCV3》ch18:相机模型与标定

简介: 省赛期间用到双目视觉的时候,只是很粗浅地调用了下API,毕竟初学而且时间紧迫。最近打算跟一个硕士生再做一个相关项目,而且也想用Stereo Vision作为毕业设计,所以很有必要了解一下其中的原理。

省赛期间用到双目视觉的时候,只是很粗浅地调用了下API,毕竟初学而且时间紧迫。最近打算跟一个硕士生再做一个相关项目,而且也想用Stereo Vision作为毕业设计,所以很有必要了解一下其中的原理。最近也在看《学习OpenCV3》这本书,里面对一些原理的阐述简明易懂,实为神书。虽然不算深入,不过也足够理解算法里面的主要思想了。所以也算是做个读书笔记吧。废话不说,开车!


img_ecbee45228861d102ec632a44f43d37b.png
封面

相机模型

针孔摄像机模型是一种简单而有用的模型,能够一定程度解释光线从物体发射到视网膜或图像采集器的几何过程。其中焦距 f 在针孔摄像机模型中,是指针孔到图像平面的距离(这里指的并不是摄像头中2.0mm,2.5mm这样的表示透镜属性的“焦距”)。Z是物体到投影中心(针孔)的距离,X是物体的长度,x是图像平面上物体的长度。由相似三角形可以得到这样的结论。

img_a5c9b52ba0d7e6fc4c73bc6d6cc4ed75.png
公式

img_bcae6d6f69bcf2a568fa5a254a6814fb.png
针孔摄像机模型

真实的针孔由于不能快速曝光收集足够的光线,所以并不是一个得到图像的好办法。这也是为什么眼睛和相机都要使用透镜这样的结构来收集光线。

我们可以简化这个模型。将图像平面放在针孔前面,针孔被理解为投影中心。光轴(Optical axis)与图像平面的较为称为主点(principal point)。这样的话图像的大小不变,而且映射的图像不会反转(回忆一下高中物理和大学物理),公式中的符号去掉了。


img_ae4e0d27ea111e9744b498c1846f652f.png
简化模型

当然这是一个很理想的模型。实际上的模型由于工艺的影响,应该写成这样的形式

img_a98d4e6e3648a7c7c41a652beebb0758.png
理想是美好的,现实是残酷的

其中受到了两方面的影响:

  • 成像装置(CMOS芯片)的中心通常不在光轴上,所以有了cx和cy两个参数,对投影屏幕坐标中心可能的偏移进行建模

  • 透镜物理焦距的偏差,导致像素是矩形的而不是正方形的。fx 实际上是指透镜在x轴上的物理焦距和成像装置每个尺寸单元 sx 的乘积。

射影几何

将物理世界中的坐标映射到投影平面上的点的过程成为“射影变换”。这样可以用齐次坐标来表示投影平面上的二维点。将相机的参数组成一个矩阵,称为“内参矩阵”。于是有以下的形式:

img_f6cd85e7b4ee9642c5508b0ae01f247c.png
M为内参矩阵,q为二维点的齐次坐标形式

img_764e8280c977e4b37ddcf8a8894db41c.png
实际的x’ = x/w,y‘类似。Q为物理世界坐标

前面讲到,针孔摄像机不能收集到足够的光线。为了能快速地生成图像,我们使用了透镜,让光线弯曲到一个点上,但代价就是带来了畸变。

Rodrigues变换

在三维空间操作时,一般使用旋转矩阵来表示空间的旋转。关于旋转矩阵更多的内容下文会给出。将矩阵乘以一个向量,就相当于将向量以某种方式旋转,但旋转矩阵的缺点就是很难直观理解各个轴旋转的角度。所以Rodrigues提出了以下公式来进行转换,这里不加推导地给出来

设旋转向量为


img_a97139f410cf475d3a0c496d7c224f06.png
旋转向量,模设为θ

那么旋转向量到旋转矩阵的变换为


img_603faacbf18b90a79e55416d3d5a8131.png
r->R

反之则有
img_331f85a20bdb15bf9ffe15158c2ef36b.png
R->r

透镜畸变

畸变分为两种,径向畸变切向畸变。径向畸变是指成像装置边缘附近的畸变,远离透镜中心的光纤比透镜中心的光线更加弯曲,如图所示。

img_563462660ecbc22dfad2b8daf85f34e6.png
径向畸变

img_7b0641fff17ada63b432041d3d7936ef.png
边缘部分畸变程度比较大

对于径向畸变,可以使用光学中心附近(即r=0)的泰勒级数的前几项来描述。一般使用前两项,鱼眼透镜则可以使用三个径向畸变项。

img_84b7dc61eab125808a6387e811bab89f.png
x轴方向
img_99eb92711219220b183f451bdb02a0fe.png
y轴方向

切向畸变则是由于制造上的缺陷使透镜不与成像平面平行而产生的,如图


img_80d1e1d9403549491f5e2c065735767e.png
切向畸变

这里不加推导地给出下面的公式,具体参考“铅锤”模型

img_2f8ae7547caf5f7e801847efa58471ec.png
矫正公式

旋转矩阵和平移向量

可以用旋转和平移来描述物体相对于相机坐标系统的相对姿态


img_0a0035d3b07c582039fb6ccd3c963575.png
旋转+平移

任何维数的旋转都可以描述为坐标向量和适当尺寸的方阵的乘积。将坐标系统旋转θ相当于将目标点绕原来的坐标轴反方向旋转θ。其中,三维物体的旋转可以分解为围绕每个轴的二维旋转。将三位物体按照某个轴旋转的旋转矩阵如下


img_9549bea1c9c8433cf227ee2783b9f4b0.png
依次绕xyz轴旋转ψ 、φ、θ

那么相乘就有
img_83480519cc254626a9b7956bf06cf98c.png
三维的旋转矩阵

平移向量用来表示如何将一个坐标系统移动到另一个坐标系统。换句话说,平移向量是第一个坐标系统的远点到第二个坐标系统的偏移量。


img_2f614b20ee8c61c6a8cca8fb0f26afdd.png
平移向量

那么物体坐标系映射到相机坐标系中的坐标的公式为
img_d8d457e8970badcda2817dc1875d36a2.png
R就是上面的旋转矩阵

标定板

没啥好说的,略


img_5e81d8096605ad88dfaefe0a7da8527e.png
标定板

单应性

之前在做全景图像拼接的时候用到过单应矩阵,可以参考这里。单应性定义为从一个平面到另一个平面的投影映射,比如说物体平面到图像平面的映射。如果我们定义

img_e16c86712e876736024f1329a3475ffb.png
观察点Q映射到成像装置的点q

那么定义 单应矩阵H

img_5d9a1283c66bf9ec5a0a46b50dbdf8f5.png
s是从H分解出来的比例因子

定义一个这样的矩阵

img_41d7610061e75e675a9780d88143fd04.png
旋转矩阵和平移向量

那么运用一些几何和线代知识,可以知道

img_20183151db46805800a3b0a95146d407.png
M就是内参矩阵,回忆一下

看上去可以推出单应矩阵了,但实际上向量Q包含了三维信息,我们只需要它在它的坐标平面上的信息。那么,我们定义一个物体平面,使它Z=0(标定板是一个平面,所以上面的点的Z可以是一样的且为0)。那么可以简化成这样的形式

img_55eecbda29400e6ba3ee602f43f220be.png
简化

顺理成章地


img_ebc7b3ebec6861ce966889b1641ad677.png
单应矩阵H

那么单应矩阵H可以用这样的方程将图像平面和目标图像平面的点相关联


img_0382dd106a14b24f8c85d3906f5faabc.png
关联

之前的文章提到,至少要用四个点来求解H。

相机标定

知道如何用数学来描述相机的内在参数和畸变特性之后,接下来一个很自然的问题就是如何使用OpenCV来进行计算。算法的调用可以看我之前写的文章,这里只记录一些原理性的东西。

回顾一下,我们需要求出四个内在参数


img_0bdf84f2b5e97f1003c0d8b99ba3b3d8.png
焦距和偏移

五个或更多的畸变参数

img_f234594b7b10df3bff520e0dd1a0dd4c.png
径向畸变参数
img_caabf80abdd6b981dea0871601f53e45.png
切向畸变参数

OpenCV中的,用于求取焦距和偏移的算法基于Zhang,畸变参数基于Brown。求解过程比较繁琐,懒得说了→_→,网上有篇博客讲的不错。

得到内参矩阵后,可以得到物理坐标到图像坐标的映射关系

img_1bd890099603a608b223ffcadcc3bf5d.png
映射

得到畸变参数之后,就能对图像进行矫正

img_9e0ac539ea30cdcd70a33d22a69a0e7a.png
没有畸变的结果

理论上只需要两个定位到角点的棋盘图像,但实际上需要10个以上才能得到比较好的结果。

得到这些参数之后,可以用OpenCV中的一些函数得到映射用的矩阵用于矫正

img_542ee9c9741b1f1f36e261938c96ebac.png
可以看到校正后线条没有弯曲

总结

这一章,我们干了这些事情:

  • 引入针孔摄像机模型,并引入透镜畸变的概念,建立起数学模型。

  • 旋转矩阵和Rodrigues变换。

  • 引入了单应性的概念,并用于相机的标定。

下一章我们会讲到双目标定和立体重建的话题。

References:
学习opencv3(中文版) —— Adrian Kaehler & Gary Bradski
三维坐标变换——旋转矩阵与旋转向量
张正友标定算法原理详解

目录
相关文章
|
24天前
|
计算机视觉 索引
OpenCV4学习笔记(2):显示相机视频流的帧率
这篇文章是OpenCV4学习笔记的第二部分,介绍了如何通过OpenCV4在显示相机视频流时计算并显示其帧率,使用`getTickCount`和`getTickFrequency`函数来测量帧时间,并用`putText`在图像上绘制帧率信息。
OpenCV4学习笔记(2):显示相机视频流的帧率
|
23天前
|
算法 计算机视觉 Python
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
该文章详细介绍了使用Python和OpenCV进行相机标定以获取畸变参数,并提供了修正图像畸变的全部代码,包括生成棋盘图、拍摄标定图像、标定过程和畸变矫正等步骤。
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
|
23天前
|
算法 定位技术 vr&ar
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
105 0
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
|
3月前
|
存储 关系型数据库 数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 多对一和多对多
【6月更文挑战第7天】该文探讨数据模型,比较了“多对一”和“多对多”关系。通过使用ID而不是纯文本(如region_id代替"Greater Seattle Area"),可以实现统一、避免歧义、简化修改、支持本地化及优化搜索。在数据库设计中,需权衡冗余和范式。文档型数据库适合一对多但处理多对多复杂,若无Join,需应用程序处理。关系型数据库则通过外键和JOIN处理这些关系。文章还提及文档模型与70年代层次模型的相似性,层次模型以树形结构限制了多对多关系处理。为克服层次模型局限,发展出了关系模型和网状模型。
44 6
|
3月前
|
SQL 人工智能 关系型数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 文档模型中Schema的灵活性
【6月更文挑战第8天】网状模型是层次模型的扩展,允许节点有多重父节点,但导航复杂,需要预知数据库结构。关系模型将数据组织为元组和关系,强调声明式查询,解耦查询语句与执行路径,简化了访问并通过查询优化器提高效率。文档型数据库适合树形结构数据,提供弱模式灵活性,但在Join支持和访问局部性上不如关系型。关系型数据库通过外键和Join处理多对多关系,适合高度关联数据。文档型数据库的模式灵活性体现在schema-on-read,写入时不校验,读取时解析,牺牲性能换取灵活性。适用于不同类型或结构变化的数据场景。
37 0
|
3月前
|
SQL JSON NoSQL
【DDIA笔记】【ch2】 数据模型和查询语言 -- 关系模型与文档模型
【6月更文挑战第6天】关系模型是主流数据库模型,以二维表形式展示数据,支持关系算子。分为事务型、分析型和混合型。尽管有其他模型挑战,如网状和层次模型,但关系模型仍占主导。然而,随着大数据增长和NoSQL的出现(如MongoDB、Redis),强调伸缩性、专业化查询和表达力,关系模型的局限性显现。面向对象编程与SQL的不匹配导致“阻抗不匹配”问题,ORM框架缓解但未完全解决。文档模型(如JSON)提供更自然的嵌套结构,适合表示复杂关系,具备模式灵活性和更好的数据局部性。
39 0
|
4月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
OpenCV读取tensorflow 2.X模型的方法:将SavedModel转为frozen graph
【2月更文挑战第22天】本文介绍基于Python的tensorflow库,将tensorflow与keras训练好的SavedModel格式神经网络模型转换为frozen graph格式,从而可以用OpenCV库在C++等其他语言中将其打开的方法~
129 1
OpenCV读取tensorflow 2.X模型的方法:将SavedModel转为frozen graph
|
4月前
|
存储 传感器 算法
相机标定系列---opencv相关标定算子
相机标定系列---opencv相关标定算子
108 0
|
4月前
|
存储 新制造 C#
Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C#)
Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C#)
55 1
|
4月前
|
传感器 存储 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现Mono12和Mono16位深度的图像保存(C++)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现Mono12和Mono16位深度的图像保存(C++)
49 0