【双目备课】《学习OpenCV第18章》相机模型与标定整编
一、相机模型
针孔模型。在这个简单模型中,想象光线是从场景或一个很远的物体发射过来的,但只有一条光线从该场景中的任意特定点进入针孔。
我们将这个图像进行抽象,就能够得到这样的结果:

其中,f为像到针孔的距离,被称为“焦距”,Z为物到针孔的距离。这里我们讨论的都是理想情况下,光轴上的距离。
那么,在该图中,我们可以通过相似三角形得到–x/f = X/Z,或

我们重新把针孔相机模型整理成另一种等价形式,使其数学形式更加简单

主要的区别在于,负号被去掉了,因为在这种模型下,像是正向的。你们这个时候,我们可以这样来表示:

实际上,芯片的中心通常不在光轴上,我们因此引入两个新的参数cx和cy,对投影屏幕坐标中心可能的偏移(对光轴而言)进行建模。

需要注意的是,这里的Xscreen/X= Sx(像素/长度),完整的公式为:

其中,只有组合量fx = f· sx和fy = f · sy可以直接计算出来而不必拆除相机去直接测量其部件。
真实的针孔由于不能为快速曝光收集足够的光线,因此它不是一个得到图像的好方法。这也是为什么眼睛和相机都要使用透镜而不是仅仅用一个点来收集更多光线的原因。
然而,对于快速生成图像的相机而言,必须利用大面积且弯曲特性,让足够多的光线能够聚焦到投影点上。为了实现这个目的,我们使用透镜。透镜可以聚焦足够多的光线到一个点上,使得图像生成更加迅速,但代价是引入了畸变。
二、(通常将相机内在矩阵的参数和畸变参数的全部集合简单地称为固有参数或内在参数。 在一些情况下,矩阵参数也被称为线性固有参数(因为它们共同定义线性变换),而畸变参数被称为非线性固有参数)。内在参数控制实际物体与生成的图像之间的线性投影变换。因此,它们与外参矩阵合在一起,告诉我们该物体实际位于何处。
畸变参数与点集在最终图像中畸变的二维几何学有关。原则上,已知图案的三个角点,产生六条信息,可能都需要用于求解我们的五个畸变参数。 因此,看起来只需要标定棋盘的一个视图就足够了。
然而,由于内在参数和外参数之间存在耦合,所以一个视图是不够的。为了理解这一点,首先要注意的是外参数包括三个旋转参数(ψ,φ,θ)和三个平移参数(Tx,Ty,Tz),每个棋盘视图共有六个外参数。由相机内在矩阵的四个参数和六个外参数共同构成十个需要求解的参数,在单个视图的情况下,每个额外的视图就会增加6个参数。
假设有N个角点和K个棋盘图像(不同位置)。我们需要看到多少视图和角点才能有足够的约束条件来求解所有这些参数?
l K个棋盘图像提供2 · N · K个约束(出现因子2是因为图像上的每个点都具有x和y两个坐标值)
l 忽略每次的畸变参数,我们有4个内在参数和6·K个外参数(因为我们需要在K个视图中找到棋盘位置的6个参数)。
l 求解的前提是2 · N · K ≥ 6 · K + 4(或等效为(N – 3) ·K ≥ 2)。
无论我们在平面上发现多少角点,我们只得到四个有用的角点信息。对于每个棋盘视图,方程只能给我们四个角点信息。而实际上需要10个或更多视图,这种差异是因为内在参数对非常小的噪声具有非常高的灵敏度。
收集并求解这些方程以找到畸变参数,之后重新估计内在参数和外参数。这些繁重的工作就是仅仅使用单个函数cv :: calibrateCamera()就能解决!3
这看上去好极了,我们希望这也确实有用
九、标定函数
一旦我们有几个图像的角点,我们可以调用cv :: calibrateCamera()。这个程序会做数字处理,并给我们提供我们想要的信息。具体来说,我们得到的结果是相机内在矩阵,畸变系数,旋转向量和平移向量。总算是最终到了这一步。
cv::InputArrayOfArrays objectPoints, // K vecs (N pts each, object frame)
cv::InputArrayOfArrays imagePoints, // K vecs (N pts each, image frame)
cv::Size imageSize, // Size of input images (pixels)
cv::InputOutputArray cameraMatrix, // Resulting 3-by-3 camera matrix
cv::InputOutputArray distCoeffs, // Vector of 4, 5, or 8 coefficients
cv::OutputArrayOfArrays rvecs, // Vector of K rotation vectors
cv::OutputArrayOfArrays tvecs, // Vector of K translation vectors
int flags = 0, // Flags control calibration options
cv::TermCriteria criteria = cv::TermCriteria(
cv::TermCriteria::COUNT | cv::TermCriteria::EPS,
30, // ...after this many iterations
DBL_EPSILON // ...at this total reprojection error
)
第一个参数是objectPoints。它是向量的向量,每个向量包含特定图像的标定图案上的点的坐标。
接下来是imagePoints参数。它也是向量的向量,并且包含每个图像中找到的每个点的位置。
imageSize参数只是告诉cv:: calibrateCamera()提取imagePoints中的点的图像有多大(以像素为单位)。
cameraMatrix 3 by 3 ,就是H了
相机的内在参数返回到cameraMatrix和distCoeffs矩阵中。 前者将包含线性内在参数,应为3×3矩阵。 后者可以是4,5或8个元素。
如果distCoeffs的长度为4,则返回的矩阵将包含系数(k1,k2,p1和p2)。 如果长度为5或8,则元素分别为(k1,k2,p1,p2和k3)或(k1,k2,p1,p2,k3,k4,k5和k6)。
【这个函数已经足够复杂了,我想使用起来寻找到一种可用的方法也许比较简单。 】
十、矫正
正如我们已经提到的,标定相机通常需要做两件事情:第一件是纠正畸变的影响,第二件是根据获得的图像重构三维场景。
矫正是在数学上去掉透镜畸变,而校正是在数学上将两个(或更多)图像整齐排列

这里应该有更棒的实现。
这个过程比较复杂,我需要不断重构强化这块内容。到这里,也就完成了本章的内容。应该说,这里的混乱还是比较明显的,如果在我的素材中能够有效地去除这些混乱,就是成功。
【双目备课】《学习OpenCV第18章》相机模型与标定整编的更多相关文章
- 《mysql必知必会》学习_第18章_20180807_欢
第18章 全文本搜索 P121 #创建一个新表,对表的列进行定义,定义之后,MySQL自动维护该索引# create table productnotes ( note_id int NOT ...
- 【双目备课】OpenCV例程_stereo_calib.cpp解析
stereo_calib是OpenCV官方代码中提供的最正统的双目demo,无论数据集还是代码都有很好实现. 一.代码效果: 相关的内容包括28张图片,1个xml和stereo_calib.cpp的代 ...
- java JDK8 学习笔记——第18章 自定义泛型、枚举与注释
第十八章 自定义泛型.枚举与注释 18.1 自定义泛型 泛型定义: (1)仅定义在方法上的泛型语法 (2)用来限制泛型可用类型的extends与super关键字(3)?类型通配字符的使用 18.1.1 ...
- 学习opencv 第六章 习题十三
用傅里叶变换加速卷积,直接上代码,Mat版是Copy他人的. CvMat版 #include "stdafx.h" #include "cv.h" #inclu ...
- 《学习OpenCV》练习题第五章第一题ab
这道题是载入一幅带有有趣纹理的图像并用不同的模板(窗口,核)大小做高斯模糊(高斯平滑),然后比较用5*5大小的窗口平滑图像两次和用11*11大小的窗口平滑图像一次是否接近相同. 先说下我的做法,a部分 ...
- 学习OpenCV双目测距原理及常见问题解答
学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化. 图 ...
- 《学习OpenCV》练习题第五章第二题abc
代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...
- 《学习OpenCV》练习题第四章第八题ab
这道题是利用OpenCV例子程序里自带的人脸检测程序,做点图像的复制操作以及alpha融合. 说明:人脸检测的程序我参照了网上现有的例子程序,没有用我用的OpenCV版本(2.4.5)的facedet ...
- 《学习OpenCV》练习题第四章第三题b
#include <highgui.h> #include <cv.h> #include "opencv_libs.h" /* *<学习OpenCV ...
随机推荐
- tshark的抓包和解析
1. a.解析dhcp抓包文件 -r 读抓好的数据包文件 tshark -r 数据包路径 -Y 过滤条件 基本上可以运用 wirshark上的过滤条件 查找中继后dhc ...
- java实现求最大子数组和的逐步显示
package 最大的子数组和; import java.util.Scanner; public class shuzu { public static int maxArr(int a[]) { ...
- [crypto][ipsec] 简述ESP协议的sequence number机制
预备 首先提及一个概念叫重放攻击,对应的机制叫做:anti-replay https://en.wikipedia.org/wiki/Anti-replay IPsec协议的anti-replay特性 ...
- rapidjson对于json的序列化与反序列化
转载: https://blog.csdn.net/qq849635649/article/details/52678822 #include "rapidjson/stringbuffer ...
- 关于autofac的一些具体的用法
简介:Autofac是一个.net下非常优秀,性能非常好的IOC容器(.net下效率最高的容器) 1.nuget 引用 2.创建两个类库项目,IService (用于编写接口),ServiceImpl ...
- ADB——管理应用
ADB应用管理 主要操作有查看应用列表.安装应用.卸载应用.清楚应用数据与缓存.查看前台Activity.查看应用信息及安装路径等等 查看应用列表 查看应用列表的基本命令格式是 adb shell p ...
- levmar : Levenberg-Marquardt库编译
levmar : Levenberg-Marquardt 是非线性优化的一个库 1.使用CMake生成sln项目,编译 clapack库 在levmar工程中,打开misc.c文件,在最开始添加#in ...
- linux架构师之路!
目录 1.shell编程总结 2.python编程总结 3.网络基础总结 4.存储的基本知识 5.linux常用 架构学习目录 1.网站架构 2.架构师技术图谱 3.python之路 4.IBM技术主 ...
- React browserHistory.push()传参
1.browserHistory.push({ "pathname":'/interface_log', state: ...
- 框架的一些bug问题记录
关于java后台生成的mis表,在添加的add页面和edit页面中无法显示,去控制台里面查看.会有些错误的信息,是由于,你的那些html的标签不正常.导致无法显示. 里面有一个高级搜索,可以对这个选择 ...