一、相机模型

针孔模型。在这个简单模型中,想象光线是从场景或一个很远的物体发射过来的,但只有一条光线从该场景中的任意特定点进入针孔。

我们将这个图像进行抽象,就能够得到这样的结果:

其中,f为像到针孔的距离,被称为“焦距”,Z为物到针孔的距离。这里我们讨论的都是理想情况下,光轴上的距离。

那么,在该图中,我们可以通过相似三角形得到–x/f = X/Z,或

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

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

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

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

其中,只有组合量fx = f· sxfy = f · sy可以直接计算出来而不必拆除相机去直接测量其部件。

真实的针孔由于不能为快速曝光收集足够的光线,因此它不是一个得到图像的好方法。这也是为什么眼睛和相机都要使用透镜而不是仅仅用一个点来收集更多光线的原因。

然而,对于快速生成图像的相机而言,必须利用大面积且弯曲特性,让足够多的光线能够聚焦到投影点上。为了实现这个目的,我们使用透镜。透镜可以聚焦足够多的光线到一个点上,使得图像生成更加迅速,但代价是引入了畸变。

二、(通常将相机内在矩阵的参数和畸变参数的全部集合简单地称为固有参数或内在参数。 在一些情况下,矩阵参数也被称为线性固有参数(因为它们共同定义线性变换),而畸变参数被称为非线性固有参数)。内在参数控制实际物体与生成的图像之间的线性投影变换。因此,它们与外参矩阵合在一起,告诉我们该物体实际位于何处。

畸变参数与点集在最终图像中畸变的二维几何学有关。原则上,已知图案的三个角点,产生六条信息,可能都需要用于求解我们的五个畸变参数。 因此,看起来只需要标定棋盘的一个视图就足够了。

然而,由于内在参数和外参数之间存在耦合,所以一个视图是不够的。为了理解这一点,首先要注意的是外参数包括三个旋转参数(ψ,φ,θ)和三个平移参数(Tx,Ty,Tz),每个棋盘视图共有六个外参数。由相机内在矩阵的四个参数和六个外参数共同构成十个需要求解的参数,在单个视图的情况下,每个额外的视图就会增加6个参数。

假设有N个角点和K个棋盘图像(不同位置)。我们需要看到多少视图和角点才能有足够的约束条件来求解所有这些参数?

K个棋盘图像提供2 · N · K个约束(出现因子2是因为图像上的每个点都具有x和y两个坐标值)

忽略每次的畸变参数,我们有4个内在参数和6·K个外参数(因为我们需要在K个视图中找到棋盘位置的6个参数)。

求解的前提是2 · N · K ≥ 6 · K + 4(或等效为(N – 3) ·K ≥ 2)。

无论我们在平面上发现多少角点,我们只得到四个有用的角点信息。对于每个棋盘视图,方程只能给我们四个角点信息。而实际上需要10个或更多视图,这种差异是因为内在参数对非常小的噪声具有非常高的灵敏度。

收集并求解这些方程以找到畸变参数,之后重新估计内在参数和外参数。这些繁重的工作就是仅仅使用单个函数cv :: calibrateCamera()就能解决!3

这看上去好极了,我们希望这也确实有用

九、标定函数

一旦我们有几个图像的角点,我们可以调用cv :: calibrateCamera()。这个程序会做数字处理,并给我们提供我们想要的信息。具体来说,我们得到的结果是相机内在矩阵,畸变系数,旋转向量和平移向量。总算是最终到了这一步。

double 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章》相机模型与标定整编的更多相关文章

  1. 《mysql必知必会》学习_第18章_20180807_欢

    第18章 全文本搜索 P121  #创建一个新表,对表的列进行定义,定义之后,MySQL自动维护该索引# create table productnotes ( note_id  int   NOT ...

  2. 【双目备课】OpenCV例程_stereo_calib.cpp解析

    stereo_calib是OpenCV官方代码中提供的最正统的双目demo,无论数据集还是代码都有很好实现. 一.代码效果: 相关的内容包括28张图片,1个xml和stereo_calib.cpp的代 ...

  3. java JDK8 学习笔记——第18章 自定义泛型、枚举与注释

    第十八章 自定义泛型.枚举与注释 18.1 自定义泛型 泛型定义: (1)仅定义在方法上的泛型语法 (2)用来限制泛型可用类型的extends与super关键字(3)?类型通配字符的使用 18.1.1 ...

  4. 学习opencv 第六章 习题十三

    用傅里叶变换加速卷积,直接上代码,Mat版是Copy他人的. CvMat版 #include "stdafx.h" #include "cv.h" #inclu ...

  5. 《学习OpenCV》练习题第五章第一题ab

    这道题是载入一幅带有有趣纹理的图像并用不同的模板(窗口,核)大小做高斯模糊(高斯平滑),然后比较用5*5大小的窗口平滑图像两次和用11*11大小的窗口平滑图像一次是否接近相同. 先说下我的做法,a部分 ...

  6. 学习OpenCV双目测距原理及常见问题解答

    学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化.  图 ...

  7. 《学习OpenCV》练习题第五章第二题abc

    代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...

  8. 《学习OpenCV》练习题第四章第八题ab

    这道题是利用OpenCV例子程序里自带的人脸检测程序,做点图像的复制操作以及alpha融合. 说明:人脸检测的程序我参照了网上现有的例子程序,没有用我用的OpenCV版本(2.4.5)的facedet ...

  9. 《学习OpenCV》练习题第四章第三题b

    #include <highgui.h> #include <cv.h> #include "opencv_libs.h" /* *<学习OpenCV ...

随机推荐

  1. 可扩展的Web架构和分布式系统

    原文链接:http://www.aosabook.org/en/distsys.html 开源软件已经成为一些大型网站的基石.随着这些网站的发展,围绕其架构的最佳实践和指导原则应运而生.本章旨在讨论设 ...

  2. sourceTree如何不用注册就使用

    下载好之后会有这么一个界面要求你注册或登录.(不管它)将下面的一串串放进我的电脑的地址栏,打开sourcetree的文件夹 %LocalAppData%\Atlassian\SourceTree\ 注 ...

  3. 严重:one or more listeners failed. Full details will be found in the appropriate container log file

    one or more listeners failed. Full details will be found in the appropriate container log file   这句话 ...

  4. Linux-centos7下python3 环境设置

    首先安装依赖包 yum -y groupinstall "Development tools" yum -y install zlib-devel bzip2-devel open ...

  5. LG1484 种树

    题意 \(N\)个数,至多选\(k\)个,相邻两数不能同时选,问最大价值. 思路 一种假的思路:直接扔进对里面,每次都选最大的可以选的,再把两边和自己标记为不能选,一直贪心下去.是不是很有道理? 假在 ...

  6. linux 逆向映射

    逆向映射用于建立物理内存页和使用该页的进程的对应页表项之间的联系,在换出页时以便更新所有涉及的进程.得到物理页基址后,根据pfn_to_page可以将页框转换为page实例,page实例中的mappi ...

  7. 【Idea】Intellij Idea debug 模式如果发现异常,即添加异常断点在发生异常处

    前用eclipse的时候,可以根据所抛出的异常进行调试,比如:出现了空指针异常,我想知道是哪一行抛出的,在eclipse中我只需在debug模式下把空指针异常这个名字设置进去,当遇到空指针异常时,ec ...

  8. ESP8266小知识与注意事项

    小知识 1. 什么是"512+512".“1024+1024”? 当ESP8266支持FOTA(无线升级)时,会给系统做个备份,当升级失败时,使之不至于死机.所以flash会被分割 ...

  9. C++实验二——函数重载、函数模板、简单类的定义和实现

    一.实验过程 函数重载编程练习 实验要求:编写重载函数add(),实现对int型,double型,complex型数据的加法.在main函数中定义不同类型的数据,调用测试. 代码实现: 先是简单的体验 ...

  10. JS中将json字符串转为json对象的三种方式

    第一种:利用JSON的parse方法,即jsonObj=JSON.parse(jsonStr); 第二种:jsonObj = eval('(' + jsonStr+ ')'); 第三种:比较难理解:j ...