OpenCV与Eigen (C++)【学习备忘】



可点击OpenCV来自简书 /// OpenCV官网
OpenCV中的单位
棋盘格边长尺寸:mm
【机器视觉】

OPENCV

  • 一、各个模块简介
  • 二 、数据类型(点类、size类、向量类、矩形类、指针类、异常类等)
  • 三、OpenCV中的Mat(矩阵)
    • 1、创建与初始化矩阵
    • 2、cv::Mat函数列表
    • 3、独立获取数组元素(访问)
    • 4、cv::Mat和std::vector之间的相互转换
      • 1、 cv::Mat转换成std::vector
      • 2、 std::vector转换成cv::Mat
      • 3、 cv::Mat_ 与cv::Mat
      • 4、CvMat,Mat和IplImage之间的转化和拷贝
    • 5、图像
      • 1、jpg
      • 2、png
      • 图像的大小(所占存储空间)与哪些因素有关?
  • 四、图像变换相关内容
    • 1、变换
      • 1.1透视变换
      • 1.2 重映射
    • 2、相机
      • 2.1 相机内参矩阵
      • 2.2 相机畸变参数
      • 2.3 相机外参
      • 2.4 相机模型
    • 3、旋转变换
    • 4、旋转矩阵及左右乘的区别
    • 5、标定相关
      • 5.1 双目标定
      • 5.2 标定原理讲解
      • 5.3 标定板创建
      • 5.4 标定板放置位置及距离要求
      • 5.5 单目相机标定
  • 五、OpenCV中函数
    • 1、CV工具函数列表
    • 2、cv::fisheye相关函数列表
  • 六、OpenCV与其他工具联合开发
    • 1、ROS 图像与 OpenCV图像 之间的转换
    • 2、OpenCV与Qt
  • 七、 Eigen相关
    • 1、各个模块介绍
    • 2、Eigen函数列表
    • 3、仿射变换矩阵
  • 八、相关理论知识(疑惑点)
  • 九、传感器相关知识

一、各个模块简介

opencv的头文件
#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"

【calib3d】:其实就是就是Calibration(校准)加3D这两个词的组合缩写。这个模块主要是相机校准和三维重建相关的内容。基本的多视角几何算法,单个立体摄像头标定,物体姿态估计,立体相似性算法,3D信息的重建等等。
【contrib】:也就是Contributed/Experimental Stuf的缩写, 该模块包含了一些最近添加的不太稳定的可选功能,不用去多管。2.4.8之后有新型人脸识别, 立体匹配 ,人工视网膜模型等技术。
【core】: 核心功能模块,尤其是底层数据结构和算法函数。包含如下内容:

(1)OpenCV基本数据结构
(2)动态数据结构
(3)绘图函数
(4)数组操作相关函数
(5)辅助功能与系统函数和宏

【imgproc】: Image和Processing这两个单词的缩写组合。图像处理模块,这个模块包含了如下内容:

(1)线性和非线性的图像滤波
(2)图像的几何变换
(3)其它(Miscellaneous)图像转换
(4)直方图相关
(5)结构分析和形状描述
(6)运动分析和对象跟踪
(7)特征检测

【features2d】: d也就是Features2D, 2D功能框架 ,包含兴趣点检测子、描述子以及兴趣点匹配框架。包含如下内容:

(1)特征检测和描述
(2)特征检测器(Feature Detectors)通用接口
(3)描述符提取器(Descriptor Extractors)通用接口
(4)描述符匹配器(Descriptor Matchers)通用接口
(5)通用描述符(Generic Descriptor)匹配器通用接口

【flann】: Fast Library for Approximate Nearest Neighbors,高维的近似近邻快速搜索算法库, 包含两个部分:快速近似最近邻搜索和聚类。
【gpu】: 运用GPU加速的计算机视觉模块。
【highgui】: 也就是high gui,高层GUI图形用户界面,包含媒体的I / O输入输出, 视频捕捉、图像和视频的编码解码、图形交互界面的接口等内容。
【legacy】: 一些已经废弃的代码库,保留下来作为向下兼容。
【ml】: Machine Learning,机器学习模块, 基本上是统计模型和分类算法,包含如下内容:

(1)统计模型 (Statistical Models)
(2)一般贝叶斯分类器 (Normal Bayes Classifier)
(3)K-近邻 (K-NearestNeighbors)
(4)支持向量机 (Support Vector Machines)
(5)决策树 (Decision Trees)
(6)提升(Boosting)
(7)梯度提高树(Gradient Boosted Trees)
(8)随机树 (Random Trees)
(9)超随机树 (Extremely randomized trees)
(10)期望最大化 (Expectation Maximization)
(11)神经网络 (Neural Networks)
(12)MLData

【nonfree】: 也就是一些具有专利的算法模块 ,包含特征检测和GPU相关的内容。最好不要商用,可能会被告哦。
【objdetect】: 目标检测模块,包含Cascade Classification(级联分类)和Latent SVM这两个部分。
【ocl】: 即OpenCL-accelerated Computer Vision,运用OpenCL加速的计算机视觉组件模块。
【photo】: 也就是Computational Photography,包含图像修复和图像去噪两部分。
【stitching】: images stitching,图像拼接模块,包含如下部分:

(1)拼接流水线
(2)特点寻找和匹配图像
(3)估计旋转
(4)自动校准
(5)图片歪斜
(6)接缝估测
(7)曝光补偿
(8)图片混合

【superres】: SuperResolution,超分辨率技术的相关功能模块。
【ts】: opencv测试相关代码,不用去管他。
【video】: 视频分析组件,该模块包括运动估计,背景分离,对象跟踪等视频处理相关内容。
【Videostab】: Video stabilization,视频稳定相关的组件。

二 、数据类型(点类、size类、向量类、矩形类、指针类、异常类等)

1.1 基础类型

6种数据类型在库中一般缩写为b=unsigned char,  w=unsigned short,  s=short,  
i=int,  f=float,  d=double

1.1.1 cv::Point类

优势:简单而且开销小。必要时,可转换为固定向量类或者固定矩阵类。
cv::Point{2,3}{b,s,i,f,d}

1.1.2 cv::Size类

详见Size数据结构,请点击

Size类在实际操作时与Point类相似,而且可以与Point类互相转换。
两者区别在于Point类的数据成员是x和y,而Size类中对应的成员是width和height。
Size类的3个别名分别是cv::Size, cv::Size2i, cv::Size2f(其中前两个是等价的)。

1.1.3 cv::Scalar类

cv::Scalar直接从固定向量类模板实例中继承而来。
cv::Scalar是四维双精度向量的快速表示。

1.1.4 cv::Rect类

矩形类包含Point类的成员x和y(矩形左上角)和Size类的成员width和height(代表了矩形的大小)。

1.1.5 cv::RotatedRect类

该类包含一个中心点cv::Point2f、一个大小cv::Size2f和一个额外的角度float的容器。

1.1.6 固定矩阵类

固定矩阵类是为编译时就已知维度的矩阵打造的,这也是称为“固定”的原因。
因为它们内部的所有数据都是在堆栈上分配的,所以它们的分配和清除很快。
固定矩阵类实际上是一个模板,这个模板称为cv::Matx<>,但独立的矩阵通常
通过别名分配。这些别名的基础格式是cv::Matx{1,2,..6}{1,2,..6}{f,d}

1.1.6 固定向量类

固定向量类是从固定矩阵类派生出来的。
固定向量模板cv::Vec{2,3,4,6}{b,s,w,i,f,d}。
固定向量类的最主要便利是它可以通过单个数索引各项,以及几个特定的额外的函数使常规矩阵运算有意义(比如叉乘)。

1.1.7 复数类

OpenCV中的复数类与STL复数类模板complex< >不一样,但与之兼容,可以相互转换。它们最大的区别在于成员获取。在STL类中,实部和虚部是通过成员函数real()和imag()获取的,而在OpenCV中,直接通过成员变量re和im获取。
复数类模板的别名是cv::Complexf和cv::Complexd,分别是单精度和双精度复数的别名。

1.1.8 辅助对象——cv::TermCriteria类

确定算法的终止条件。
cv::TermCriteria有三个成员变量(type,maxCount以及epsilon)
源码结构如下:
struct cv::TermCriteria(
Public:
//成员变量
enum
{
COUNT=1,	//计算元素或者迭代次数最小值
MAX_ITER=COUNT, //最大迭代次数
EPS=2	//当满足该精确度时,迭代算法停止
};

//构造函数
TermCriteria::TermCriteria()
TermCriteria::TermCriteria(int type, int maxCount, double epsilon)
TermCriteria::TermCriteria(const CvTermCriteria& criteria)
//参数:
  //type –	终止条件类型:
  //maxCount –	计算的迭代数或者最大元素数
  //epsilon – 当达到要求的精确度或参数的变化范围时,迭代算法停止

  //type可选:
	//TermCriteria::COUNT //达到最大迭代次数 =TermCriteria::MAX_ITER
	//TermCriteria::EPS	//达到精度
	//TermCriteria::COUNT + TermCriteria::EPS //以上两种同时作为判定条件
);
上一个例子:
cv::TermCriteria  criteria = cv::TermCriteria(
							cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 10, 0.1);
//COUNT=MAX_ITER(相等)

1.1.9 辅助对象——cv::Range类

cv::Range类用于确定一个连续的整数序列。构造函数cv::Range(int start, int end)中,范围包含初始值start,但不包含终止值end。
cv::Range类成员函数还有size(), empty()

1.1.10 辅助对象——cv::Ptr模板和垃圾收集

指针模板的实例:可以通过调用类似
cv::Ptr<cv::Matx33f> p(new cv::Matx33f)
或
cv::Ptr<cv::Matx33f> p = cv::makePtr<cv::Matx33f>() #这种格式在3.0版本可以,在4.0版本好像不能用了
cv::Ptr<> 是线程安全的。

1.1.11 辅助对象——cv::Exception类和异常处理

请添加

1.1.12 辅助对象——cv::DataType<>模板

请添加

三、OpenCV中的Mat(矩阵)

1、创建与初始化矩阵

请点击–> 【OpenCV3】cv::Mat的定义与初始化
请点击–> OpenCV Mat类详解和用法

补充:创建矩阵
C++: void Mat::create(int rows, int cols, int type
C++: void Mat::create(Size size, int type)
C++: void Mat::create(int ndims, const int* sizes, inttype)
参数:
ndims – 新数组的维数。   rows –新的行数。
cols – 新的列数。        size – 替代新矩阵大小规格:Size(cols, rows)。
type – 新矩阵的类型。    sizes – 指定一个新的阵列形状的整数数组。
示例:
cv::Mat srcImage = cv::imread("D:\\visual studio 2010\\Projects\\remap\\1.jpg");
cv::Mat dstImage;
dstImage.create(srcImage.size(),srcImage.type());

建立矩阵必须要指定矩阵存储的数据类型,图像处理中常用的几种数据类型如下:

CV_8UC{1,2,3,4}   // 8位无符号单通道, 双通道,3通道,4通道
CV_8SC{1,2,3,4}   // 8位短整型单通道, 双通道,3通道,4通道
CV_16UC{1,2,3,4}  // 16位无符号单通道, 双通道,3通道,4通道
CV_16SC{1,2,3,4}  // 16位短整型单通道, 双通道,3通道,4通道
CV_32SC{1,2,3,4}  // 32位短整型单通道, 双通道,3通道,4通道
CV_32FC{1,2,3,4}  // 32位浮点型单通道, 双通道,3通道,4通道
CV_64FC{1,2,3,4}  // 64位浮点型单通道, 双通道,3通道,4通道
!!!!!强调:数组中的数据是按行连续组织的,因此不可以通过这种方式去访问一个指定的列。

2、cv::Mat函数列表

cv::Mat函数(全)名称 描述
cv::Mat::reshape() reshape函数既可以改变通道数,又可以对矩阵元素进行序列化
cv::Mat::isContinuous() 返回bool值,判断存储是否连续,如果矩阵的行之间没有空隙,返回true
cv::Mat::clone() m1 = m0.clone();
将m0完全拷贝到m1中,同时拷贝m0中的所有数据,且拷贝的矩阵是连续的。
cv::Mat::convertTo() void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
主要是根据公式dst = alpha * src + beta(alpha控制对比度,beta控制亮度)
m0.convertTo(m1, type, alpha, beta); 类型转换,但不能转换通道数 。
将m0中的元素转换成type类(CV_32F等)。
对比度亮度图像增强及convertTo详解
cv::Mat::push_back() m0.push_back(s); //对mx1矩阵进行扩展,并在末尾插入单一值s。
m0.push_back(m1); //对大小为mxn矩阵m0作k行扩展,并将m1拷贝到这些行中;m1的大小必须为kxn。
cv::Mat::pop_back() m0.pop_back(n); //从m0尾部移除n行,默认情况下n为1。
cv::Mat::type() m0.type(); //返回m0中元素的有效类型标识符(如CV_32FC3)。
cv::Mat::depth() m0.depth(); //返回m0中单个通道中元素的有效类型标识符(如CV_32F)。
cv::Mat::channels() m0.channels(); //返回m0中元素的通道数目。
cv::Mat::size() m0.size(); //以cv::Size对象的形式返回m0的大小。
cv::Mat::empty() m0.empty(); //如果数组中没有元素(如m0.total == 0 或 m0.data == NULL)则返回true。
cv::Mat::ptr 常用形式: mat.ptr(row)[col] 对于Mat的ptr函数,返回的是<>中的模板类型指针,指向的是()中的第row行的起点,通常<>中的类型和Mat的元素类型应该一致,然后再用该指针去访问对应col列位置的元素
cv::Mat::inv( method ) 求矩阵的逆矩阵,method有3种:cv::DECOMP_LU(默认),cv::DECOMP_CHOLESKY,cv::DECOMP_SVD。
cv::Mat::cross() 计算3元素向量的一个叉乘积。只适用于3×1矩阵
cv::Mat::dot() 计算两向量的点乘。
cv::Mat::mul() 计算两个Mat矩阵对应位的乘积,所以要求参与运算的矩阵A的行列和B的行列数一致。
函数原型:C++: MatExpr Mat::mul(InputArray m, double scale=1) const。
用法:Mat AB=A.mul(B);
cv::Mat::t() 矩阵的转置运算
cv::Mat::rowRange() && cv::Mat::colRange() rowRange为指定的行span创建一个新的矩阵头,可取指定行区间元素;colRange为指定的列span创建一个新的矩阵头,可取指定列区间元素。from官网
cv::Mat::
cv::Mat::
cv::Mat::
cv::Mat::
cv::Mat::
cv::Mat::
cv::UMat 它跟Mat有着多数相似的功能和相同的API函数,通过使用UMat对象,OpenCV会自动在支持OpenCL的设备上使用GPU运算,在不支持OpenCL的设备仍然使用CPU运算,这样就避免了程序运行失败,而且统一了接口。

3、独立获取数组元素(访问)

请点击-> cv::Mat像素遍历方式(3种)

请点击-> 访问Mat中每个像素的值

4、cv::Mat和std::vector之间的相互转换

1、 cv::Mat转换成std::vector

(1)
cv::Mat mat;
std::vector<type_> vec;
vec = (std::vector<type_>)(mat.reshape(0,1));
reshape函数原型:C++: Mat Mat::reshape(int cn, int rows=0) const
cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数。
rows: 表示矩阵行数。如果设为0,则表示保持原有的行数不变,否则则变为设置的行数。
用法:
cv::Mat data = Mat(20, 30, CV_32F);
cv::Mat dst = data.reshape(0, 1);
(2)
cv::Mat M(rows,cols, CV_32FC1 );
std::vector<float> V;
V.assign ( (float*)M.datastart, (float*)M.dataend );

2、 std::vector转换成cv::Mat

(1)
使用Mat的构造函数
std::vector<type_> vec;
cv::Mat mat;
mat = cv::Mat(vec, true);
(2)
std::vector<type_> V;
cv::Mat M2=cv::Mat(rows,cols,CV_32FC1);
memcpy(M2.data,V.data(),V.size()*sizeof(type_));
memcpy函数
   头文件:
   C:#include<string.h>
   C++:#include<cstring>
   函数原型:
   void *memcpy(void *dest, const void *src, size_t n);
   功能:
   从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

3、 cv::Mat_ 与cv::Mat

/
cv::Mat_
创建一个cv::Mat_并赋值
 cv::Mat_<double> mat(3,3); //要注明类型double
 mat(0,0)=VIRTUAL_FOCAL;
 mat(0,1)=0;
 mat(0,2)=roiSize_x/2;
 mat(1,0)=0;
 mat(1,1)=VIRTUAL_FOCAL;
 mat(1,2)=roiSize_y/2;
 mat(2,0)=0;
 mat(2,1)=0;
 mat(2,2)=1;
使用cv::Mat_类模板的话,at()方法不需要指明类型,如下:
cv::Mat_<Vec2f> m( 10, 10 );
m.at( i0, i1 ) = cv::Vec2f( x, y );
/
cv::Mat

...........

4、CvMat,Mat和IplImage之间的转化和拷贝

请点击-> CvMat,Mat和IplImage之间的转化和拷贝

5、图像

1、jpg

(1)JPEG英文全名是Joint Photographic Experts Group,JPG格式是一种有损压缩格式。
(2)由于JPG是有损格式,将图像压缩在很小的储存空间,一定程度上会造成图像数据的损伤,会造成锯齿状边缘。
(3)

2、png

(1)PNG图片格式全称是Portable Network Graphics,PNG是无损压缩算法的位图格式。
(2)PNG可以为原图像定义256个透明层次,使图片边缘平滑融合,从而消除图片锯齿边缘。
(3)PNG支持透明效果,可以作为背景透明的图片使用。
(4)PNG图片,体积小、清晰度高,锯齿情况少,并且兼容性非常强,PNG便携式网络图形,是一种采用无损压缩算法的位图格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。

图像的大小(所占存储空间)与哪些因素有关?

(1)分辨率
分辨率是指一张图像在每英寸内有多少像素点,相同尺寸的两张图片,分辨率越高,图像文件越大,分辨率相同的两张图片,图像尺寸越大,图像文件越大,也就是说图像文件的大小取决于前两者的参数,随这两者的改变而改变。
(2)图像深度
图像深度是指存储每个像素所用的位数,它也是用来度量图像的色彩分辨率的。它确定了彩色图像的每个像素可能有的色彩数,或者确定灰度图像的每个像素可能有的灰度级数。它决定了色彩图像中可能出现的最多的色彩数,或者灰度图像中的最大灰度等级。

图像深度是单个像素点的色彩详细度,如16位(65536色),32位等。比如一幅单色图像,若每个像素有8位,则最大灰度数目为2的8次方,即256.一幅彩色图像RGB 3个温良的像素位数分别为4,4,2,则最大颜色数目为2的4+4+2次方,即1024,就是说像素的深度为10位,每个像素可以是1024种颜色中的一种,例如:一幅画的尺寸是 1024*768,深度为16,则它的数据量为1.5M。

计算如下:
1024 * 768 * 16bit = (1024 * 768 * 16) / 8字节
= [(1024 * 768 * 16) / 8] / 1024KB
= {[(1024 * 768 * 16) / 8] / 1024} / 1024MB
=1.5MB。

(3)存储格式
不同的存储格式,压缩技术也会导致图像的大小不同,例如同一张图片,用JPG,PNG,BMP等格式图像大小会有差异,这个知道就行,不进行深度分析。

四、图像变换相关内容

1、变换

1.1透视变换

1、 请点击-> 透视变换——cv::getPerspectiveTransform()与cv::warpPerspective()详解

2、 请点击-> 鱼眼相机外参的计算和图像的透视变换

3、 请点击-> uvc鱼眼相机畸变矫正标定、透视图变换为IPM图(鸟瞰图/俯视图)

1.2 重映射

1、坐标映射(remap重映射)

2、相机

2.1 相机内参矩阵

请点击–> 相机内参矩阵 ( Camera Matrix )
请点击–> 针孔相机模型和相机内参矩阵K
相机内参矩阵K:

OpenCV与Eigen (C++)【学习备忘】_第1张图片

内参矩阵K包括5个未知参数。一般情况下,摄像机倾斜因子s=0。因此K就只有4个未知参数了,f_{x}表示焦距在图像坐标系u轴方向的位置,f_{y}表示焦距在图像坐标系v轴方向的位置,c_{x}表示光心在图像坐标系u轴方向的位置,c_{y}表示光心在图像坐标系v轴方向的位置。
OpenCV与Eigen (C++)【学习备忘】_第2张图片

2.2 相机畸变参数

桶形畸变 (Barrel Distortion)又称桶形失真,是指光学系统引起的成像画面呈桶形膨胀状的失真现象。桶形畸变在摄影镜头成像尤其是广角镜头成像时较为常见。使人变矮胖的哈哈镜成像是桶型畸变的一个比较形象的例子。
枕形畸变(Pincushion Distortion)又称枕形失真,它是指光学系统引起的成像画面向中间“收缩”的现象。枕形畸变在长焦镜头成像时较为常见。使人变瘦高的哈哈镜成像属于枕型畸变。
OpenCV与Eigen (C++)【学习备忘】_第3张图片

2.3 相机外参

请点击–> 像素坐标转到世界坐标时相机坐标系中的Zc值求解-理论公式 ,可用于验证外参标定结果准确性。
请点击–> 代码链接
代码如下:

cv::Mat uvPoint = (cv::Mat_<double>(3,1) << 363, 222, 1); 
cv::Mat Mat_1  = rotationMatrix.inv() * cameraMatrix.inv() * uvPoint;
cv::Mat Mat_2 = rotationMatrix.inv() * tvec;
//285 represents the height Zw
// s Equivalent to Zc
double s = (285 + Mat_2.at<double>(2,0))/Mat_1.at<double>(2,0)); 
std::cout << "P = " << rotationMatrix.inv() * (s * cameraMatrix.inv() * uvPoint - tvec) << std::endl;

2.4 相机模型

请点击–> 相机模型–针孔相机投影(pinhole camera model)
请点击–> 相机模型-鱼眼模型(fisheye camera model)

3、旋转变换

请点击–> 旋转变换(一)旋转矩阵

4、旋转矩阵及左右乘的区别

请点击–> 旋转矩阵及左右乘的意义,看这一篇就够了

5、标定相关

相机标定方法分三类:
1.传统摄像机标定方法
特点:利用已知的景物结构信息。常用到标定块。
优点:可以使用于任意的摄像机模型,标定精度高
不足:标定过程复杂,需要高精度的已知结构信息。在实际应用中很多情况下无法使用标定块。
常用方法:Tsai两步法、张氏标定法
2.主动视觉摄像机标定方法
特点:已知摄像机的某些运动信息
优点:通常可以线性求解,鲁棒性比较高
不足:不能使用于摄像机运动未知和无法控制的场合
常用方法:主动系统控制相机做特定运动
3.摄像机自标定方法
特点:仅依靠多幅图像之间的对应关系进行标定
优点:仅需要建立图像之间的对应,灵活性强,潜在应用范围广。
不足:非线性标定,鲁棒性不高
常用方法:分层逐步标定、基于Kruppa方程
以张正友标定法为例:使用二维方格组成的标定板进行标定,采集标定板不同位姿图片,提取图片中角点像素坐标,通过单应矩阵计算出相机的内外参数初始值,利用非线性最小二乘法估计畸变系数,最后使用极大似然估计法优化参数。该方法操作简单,而且精度较高,可以满足大部分场合。

请点击–> 一文读懂重投影误差

请点击–> 鱼眼镜头的成像原理到畸变矫正(完整版)

请点击–> 张正友标定算法原理详解

5.1 双目标定

请点击–> OPENCV3.0 双目立体标定

请点击–> Camera Calibration and 3D Reconstruction(内含各种标定函数与3D重建函数)

请点击–> 双目测距与三维重建的OpenCV实现问题集锦(一)图像获取与单目标定

请点击–> 双目测距与三维重建的OpenCV实现问题集锦(二)双目定标与双目校正

请点击–> 双目测距与三维重建的OpenCV实现问题集锦(三)立体匹配与视差计算

请点击–> 双目测距与三维重建的OpenCV实现问题集锦(四)三维重建与OpenGL显示

请点击–> 双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python

三角测量(测距原理)
视差是指在左右摄像机观察得到的相同特征在x坐标上的差值,如下图中的d。

OpenCV与Eigen (C++)【学习备忘】_第4张图片
图1. 双摄像头模型俯视图

OpenCV与Eigen (C++)【学习备忘】_第5张图片

图2, 双摄像头模型立体视图
在这种简化的情况下,可以发现深度与视差成反比,通过相似三角形容易求出深度Z,得到下式:
在这里插入图片描述
得出结论,立体视觉系统只有在物体与摄像机距离较近时才具有较高的深度分辨率,如下图所示。
OpenCV与Eigen (C++)【学习备忘】_第6张图片
请点击–> 双目相机选择——镜头与相机的参数介绍及选择

5.2 标定原理讲解

请点击–> 最详细、最完整的相机标定讲解

5.3 标定板创建

请点击–> 创建生成ChArUco标定板
请点击–> 生成Aprilgrid标定板
请点击–> 相机标定与3D重建(1)创建标定板(上)
请点击–> OPENCV官网–aruco相关函数介绍(ArUco Marker Detection)

5.4 标定板放置位置及距离要求

请点击–> 相机标定过程中的注意事项
1、相机镜头标靶硬件搭配:
①同样视场范围内相机的分辨率越大,标定精度越高;
②镜头决定视场范围,标靶大小小于视场的1/5时会减小摄像机的标定精度。
③图像张数要求15-20张(但并不是越多越好),标靶出现在图像的任意位置,标靶平面与相机平面倾斜角度小于45度。
2、操作技巧:
①将标靶放在相机景深范围内,调节好镜头焦距和光圈,使标靶能够清晰成像;
②标定是将标靶放在测量区域内进行标定,在哪儿测量在那儿标定;
③标定时标靶处于静止状态或小幅度的晃动,减少由于相机的曝光时间引起的运动模糊造成的误差;
④使标靶尽可能多的放置在系统测量范围内不同位置进行标定;
⑤在测量范围的深度方向上(Z方向)有一定的平移,或绕X轴和Y轴有一定的旋转;
3、外界环境干扰:
①光线过亮或过暗,标靶特征圆与背景对比度低,会引起检测不到标靶,或检测精度低;
②光照不均匀,使得标靶部分过亮或过暗会也引起检测不到标靶,或检测精度低;

5.5 单目相机标定

请点击–> 鱼眼相机标定-基于张正友标定法

五、OpenCV中函数

1、CV工具函数列表

CV工具函数名称 描述
cv::abs() 计算矩阵中所有元素的绝对值
cv::absdiff() 计算两个矩阵差值的绝对值
cv::add() 实现两个矩阵逐元素相加
cv::addWeighted 实现两个矩阵逐元素加权求和(alpha blending)
cv::bitwise_and 计算两个矩阵逐元素按位与
cv::bitwise_not 计算两个矩阵逐元素按位非
cv::bitwise_or 计算两个矩阵逐元素按位或
cv::bitwise_xor 计算两个矩阵逐元素按位异或
cv::calcCovarMatrix() 计算一组n维向量的协方差
cv::cartToPolar() 计算二维向量的角度和幅度
cv::checkRange() 检查矩阵的无效值
cv::compare() 对两个矩阵中的所有元素应用所选择的比较运算符
cv::completeSymm() 通过将一半元素复制到另一半来使矩阵对称
cv::convertScaleAbs() 缩放矩阵,取绝对值,然后转换为8位无符号数
cv::countNonZero() 计算矩阵中非零元素个数
cv::arrToMat() 将2.1版本的矩阵类型转换为cv::Mat
cv::dct() 计算矩阵的离散余弦变换
cv::determinant() 计算方阵的行列式
cv::dft() 计算矩阵的离散傅里叶变换
cv::divide() 实现两个矩阵逐元素相除
cv::eigen() 计算方阵的特征值和特征向量
cv::exp() 实现矩阵的逐元素求指数幂
cv::extractImageCOI() 从2.1版本的矩阵类型中提取单个通道
cv::flip() 绕选定的轴翻转矩阵
cv::gemm() 实现广义矩阵乘法
cv::getConvertElem() 获取单像素类型转换函数
cv::getConvertScaleElem() 获取单像素类型的转换和缩放函数
cv::idct() 计算矩阵的离散余弦逆变换
cv::idft() 计算矩阵的离散傅里叶逆变换
cv::inRange() 测试矩阵的元素是否再两个其他矩阵的值之间
cv::invert() 求矩阵的逆,
函数原型:double cv::invert(InputArray src, OutputArray dst, int flags = DECOMP_LU )
cv::log() 计算矩阵逐元素的自然对数
cv::magnitude() 计算二维向量的幅度
cv::LUT() 将矩阵转换为查找表的索引
cv::Mahalanobis() 计算两个向量之间的马氏距离
cv::max() 计算两个矩阵逐元素的最大值
cv::mean() 计算矩阵元素的平均值
cv::meanStdDev() 计算矩阵元素的均值和和标准差
cv::min() 计算两个矩阵逐元素的最小值
cv::minMaxLoc() 在矩阵中寻找最小值和最大值
cv::mixChannels() 打乱从输入矩阵到输出矩阵的通道
cv::mulSpectrums() 计算两个傅里叶谱的逐元素乘积
cv::multiply() 计算两个矩阵的逐元素乘积
cv::mulTransposed() 计算矩阵和矩阵的转置的乘积
cv::norm() 计算两个矩阵的归一化相关系数(求范数),
函数原型:double cv::norm (InputArray src1, int normType=NORM_L2, InputArray mask=noArray())
cv::normalize() 将矩阵中的元素标准化到某一数值内,共有4种归一化类型。共两种入参形式,from官网
cv::perspectiveTransform() 实现一系列向量的透视矩阵变化
cv::phase() 计算二维向量的方向
cv::polarToCart() 已知角度和幅度,求出对应的二维向量
cv::pow() 对矩阵内的每个元素求幂
cv::randu() 用均匀分布的随机数填充给定的矩阵
cv::randn() 用正态分布的随机数填充给定的矩阵
cv::randShuffle( InputOutputArray dst, double iterFactor = 1.0, RNG* rng = 0 ) 随机打乱矩阵元素
void cv::reduce( ) 通过特定的操作将n维矩阵缩减为一维向量
cv::repeat() 将一个矩阵的内容复制到另一个矩阵
cv::saturate_cast<>() 转换原始类型(模板函数),饱和转换,防止上溢出或下溢出
cv::scaleAdd() 逐元素计算两个矩阵的和并且第一个矩阵可以选择缩放
cv::setIdentity() 将矩阵中对角线上的元素设为1,其他置0
cv::solve() bool cv::solve ( InputArray src1, InputArray src2, OutputArray dst, int flags = DECOMP_LU ),求出线性方程的解, 解决一个或多个线性系统或最小二乘问题
cv::solveCubic() 找到(唯一的)三次方程的解
cvRound(), cvFloor(), cvCeil() 函数cvRound,cvFloor,cvCeil 都是用一种舍入的方法将输入浮点数转换成整数
cv::solvePoly() 找到多项式方程的复根
cv::sort() 在矩阵中排序任意行或列的元素
cv::sortIdx()与cv::sort() 目的相同,除了矩阵是未修改的,并返回索引
cv::split() 将一个多通道矩阵分割成多个单通道矩阵
cv::merge() 将多个单通道矩阵合并成一个多通道矩阵
cv::sqrt() 计算矩阵逐元素的平方根
cv::subtract() 实现两个矩阵逐元素相减
cv::sum() 对矩阵中的所有元素求和
cv::theRNG() 返回随机数生成器
cv::RNG 随机数发生器 。用RNG产生随机数
cv::trace() 计算一个矩阵的迹
cv::transform() 在矩阵的每个元素上应用矩阵变换
cv::transpose() 矩阵的转置运算
cv::goodFeaturesToTrack() 角点检测
cv::cornerSubPix( InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria ) 亚像素检测
InputArray image为灰度图像
cv::perspectiveTransform() void perspectiveTransform(InputArray src, OutputArray dst, InputArray mat)
透视变换一系列点,用于稀疏透视变换 。矩阵mat可以是3×3或4×4矩阵,如果是3×3,则投影从二维到二维;如果是4×4,则投影从三维到三维。
cv::getPerspectiveTransform() 计算出透视变换矩阵M(单应矩阵H)
cv::warpPerspective() 透视变换得到鸟瞰图
cv::setMouseCallback() 回调函数中鼠标响应, 首先明确一点,这个函数在程序中始终运行,任何时候当你的鼠标有动作的时候,该函数被调用。
cv::cvtColor() 用于将图像从一个颜色空间转换到另一个颜色空间的转换(目前常见的颜色空间均支持),并且在转换的过程中能够保证数据的类型不变,即转换后的图像的数据类型和位深与源图像一致。
void cv::remap ( InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode = BORDER_CONSTANT, const Scalar & borderValue = Scalar() ) Applies a generic geometrical transformation to an image,就是把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去,形成一张新的图像。
cv::PCA::PCA() && 原理 (1) cv::PCA::PCA ()默认构造;
(2)cv::PCA ::PCA(InputArray data, InputArray mean, int flags, int maxComponents=0);
(3)cv::PCA ::PCA(InputArray data, InputArray mean, int flags, double retainedVariance)
cv::randu
cv::randn
void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0) 设置鼠标事件回调,
@param winname 需要设置回调的窗口名称
@param onMouse 回调函数typedef void (MouseCallback)(int event, int x, int y, int flags, void userdata);
@param userdata 用户自定义数据,作为回调函数的第5个参数
double cv::calibrateCamera () 单目相机,根据校准模式的几个视图(也就是相机拍的几张不同的图片),求解摄像机的内在参数和外在参数。
返回值是 均方根(RMS)重投影误差,正确校准时,应介于0.1~1.0像素之间。
cv::threshold() 直接阈值化 double cv::threshold( cv::InputArray src, // 输入图像
cv::OutputArray dst, // 输出图像
double thresh, // 阈值
double maxValue, // 向上最大值
int thresholdType // 阈值化操作的类型 );
cv::adaptiveThreshold() 自适应阈值化 void cv::adaptiveThreshold( cv::InputArray src, // 输入图像
cv::OutputArray dst, // 输出图像
double maxValue, // 向上最大值
int adaptiveMethod, // 自适应方法,平均或高斯
int thresholdType // 阈值化类型
int blockSize, // 块大小
double C // 常量 );
cv::findChessboardCorners() 棋盘格角点检测的函数,仅提供角点的近似位置
返回值为bool类型
所需头文件:#include
cv::find4QuadCornerSubpix ( InputArray img, InputOutputArray corners, Size region_size) 找到棋盘角的亚像素精确位置。作用同cornerSubPix()函数
返回值为bool类型
所需头文件:#include
cv::drawChessboardCorners() 用于绘制棋盘格角点的函数
所需头文件:#include
bool cv::solvePnP ( InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess = false, int flags = cv::ITERATIVE ); 从3D-2D点对应关系中找到一个对象的姿态。如果场景的三维结构已知,利用多个控制点在三维场景中的坐标及其在图像中的透视投影坐标即可求解出摄像机坐标系与表示三维场景结构的世界坐标系之间的绝对位姿关系,该类求解方法统称为 N点透视求解(Perspective-N-Point,PNP问题)
使用cv::Rodrigues()函数主要用于将cv:: solvePnP() {from官网}和cv::calibrateCamera()的输出从Rodrigues格式的1x3或3x1向量转化为旋转矩阵,反之亦然。
bool cv::solvePnPRansac() cv::solvePnP的一个缺点是对异常值不够鲁棒(针对棋盘格相机标定影响不大)。
void cv::Rodrigues ( InputArray src, //输入旋转向量or矩阵
OutputArray dst, //输出旋转矩阵or向量
OutputArray jacobian = noArray() )
将旋转矩阵转换为旋转向量,反之亦然(from官网)
cv::cv2eigen()
cv::eigen2cv();
这两个函数都要输入两个参数,第一个参数为输入的矩阵,第二个参数为输出的矩阵。
所需头文件:#include
#include
#include “opencv2/opencv.hpp”
cv::getTextSize() 获取一个文字的宽度和高度
cv::putText() 在图片上绘制指定文字
void cv::setWindowProperty(const String &winname, int prop_id, double prop_value) 设置窗口属性(from官网)
cv::getWindowProperty(winname, prop_id) 得到窗口属性(from官网)
void cv::namedWindow (const String &winname, int flags=WINDOW_AUTOSIZE) 命名一个窗口(from官网)
void cv::destroyWindow (const String &winname) 销毁一个窗口(from官网)
void resize( InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0,
int interpolation = INTER_LINEAR );
尺寸调整(from官网)
cv::Mat cv::findFundamentalMat() 计算基本矩阵F(from官网)
cv::Mat findEssentialMat() 计算本征矩阵E(from官网)
基本矩阵、本征矩阵和单应矩阵的讲解 基本矩阵F和本征矩阵E没有什么差别,基础矩阵F是在图像像素坐标中操作,而本征矩阵E在物理坐标系(纯几何)中操作
void cv::computeCorrespondEpilines() 根据一幅图像中的点列,计算其在另一幅图像中对应的极线。
void projectPoints(InputArray objectPoints, InputArray rvec, InputArray tvec, InputArray cameraMatrix, InputArray distCoeffs, OutputArray imagePoints, OutputArray jacobian=noArray(), double aspectRatio=0 ) from 官网-函数projectPoints()根据所给的3D坐标和已知的几何变换来求解投影后的2D坐标。
通过给定的内参数和外参数计算三维点投影到二维图像平面上的坐标。 重投影误差显示在图像上。
double cv::stereoCalibrate( ) 标定立体相机(双目相机)(from官网) 。
imagePoints1包含第一个(通常是左侧)摄像机观察到的点。返回值是 均方根(RMS)重投影误差,正确校准时,应介于0.1~1.0像素之间。
双目标定 块匹配算法 cv::StereoBM from官网
双目标定 半全局块匹配算法 cv::StereoSGBM from官网
cv::circle() 画圆
cv::waitKey(delay = 0) 1、delay≤0:一直等待按键;
2、delay取正整数:等待按键的时间(ms)。
该函数的返回值:
等待期间有按键:返回按键的ASCII码(比如:Esc的ASCII码为27);
等待期间没有按键:返回值为 -1;
用法:char c = (char)waitKey();
if( c == 27 逻辑或 c== ‘q’ 逻辑或 c == ‘Q’ ) break;
cv::glob() 作用:读取文件夹中数据,from官网
cv::mixChannels() 作用:将输入数组的指定通道复制到输出数组的指定通道。from官网
类 cv::CommandLineParser &&& second link 命令行解析类
cv::getTickCount() 该函数为opencv中的函数,该函数返回的值为自从某一时刻(比如计算机启动)开始,计算机总共经过的tick的次数,其需要结合getTickFrequency()函数使用,getTickFrequency()返回的是CPU在一秒钟内会发出的tick的次数,总体来说,该函数的精度较高,能够精确到1ms左右。
举例:double t = (double)getTickCount();
t = ((double)getTickCount()-t)/getTickFrequency();
//获得时间,单位是秒
cv::FileStorage 类 from官方连接。FileStorage类将各种OpenCV数据结构的数据存储为XML 或 YAML格式并对xml,yml等文本文件的读写。
类中成员函数:
wtrite()
read()
writeComment()
等等
cv::FileStorage::writeComment ( const String & comment, bool append = false ) 函数作用:写注释。该函数将注释写入文件存储。读取存储时,将跳过注释。参数解释:(1)comment:书面评论,单行或多行;(2)append:如果为true,函数将尝试将注释放在当前行的末尾。否则,如果注释是多行的,或者它不适合在当前行的末尾,则注释将开始一个新行。
cv::FileNode 类 OpenCV读取XML或YML文件
void cv::hconcat( )
水平拼接函数
对给定矩阵应用水平连接。from-opencv官网
void cv::vconcat( )
垂直拼接函数
对给定矩阵应用垂直连接。from-opencv官网
cv::aruco
作用:ArUco Marker Detection
from-opencv官网
void cv::meanStdDev () 用于计算一个矩阵的均值和标准差。from-opencv官网
cv::drawMarker() 图像上绘制标记
cv::Mat cv::estimateAffinePartial2D() Computes an optimal limited affine transformation with 4 degrees of freedom between two 2D point sets. from-opencv官网
所需头文件: #include
cv::Mat cv::estimateAffine2D() Computes an optimal affine transformation between two 2D point sets. from-opencv官网 表示的是六自由度的仿射变换
所需头文件: #include
class cv::detail::MultiBandBlender 多波段图像融合 from官网
需包含头文件:#include “blenders.hpp”
double cv::kmeans ( InputArray data, int K, InputOutputArray bestLabels, TermCriteria criteria, int attempts, int flags, OutputArray centers = noArray() ) K-means,即K均值, 是一种迭代求解的聚类算法。
KMeans 算法

2、cv::fisheye相关函数列表

鱼眼镜头是一种极端的广角镜头,通常焦距小于等于16mm并且视角接近或等于180°(在工程上视角超过140°的镜头即统称为鱼眼镜头)。
鱼眼镜头常用的投影方式包括等距投影、等积投影、体视投影、正交投影等;

cv::fisheye相关函数from官网 描述
cv::getOptimalNewCameraMatrix() + cv::fisheye::initUndistortRectifyMap() + cv::remap() 结果等同于下面的函数
需包含头文件:#include
void cv::fisheye::undistortImage ( InputArray distorted, OutputArray undistorted, InputArray K, InputArray D, InputArray Knew=cv::noArray(), const Size &new_size=Size() ) Transforms an image to compensate for fisheye lens distortion,变换图像以补偿鱼眼镜头的畸变
参数:
distorted
undistorted
image with fisheye lens distortion。

Output image with compensated fisheye lens distortion
参数:
K
D
K:相机矩阵
D: Input vector of distortion coefficients (k1,k2,k3,k4)
参数: Knew = cv::noArray() 。

new_size = Size()
Camera matrix of the distorted image. By default, it is the identity matrix but you may additionally scale and shift the result by using a different matrix,扭曲图像的相机矩阵。默认情况下,它是单位矩阵,但您可以通过使用不同的矩阵来缩放和移动结果。

矩阵的尺寸
double cv::fisheye::calibrate (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size &image_size, InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags=0, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 100, DBL_EPSILON)) Performs camera calibration(执行相机标定)from官网
cv::fisheye::distortPoints (InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha=0) Distorts 2D points using fisheye model,使用鱼眼模型扭曲2D点
double cv::fisheye::stereoCalibrate (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray K1, InputOutputArray D1, InputOutputArray K2, InputOutputArray D2, Size imageSize, OutputArray R, OutputArray T, int flags=fisheye::CALIB_FIX_INTRINSIC, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 100, DBL_EPSILON)) Performs stereo calibration,执行立体相机标定
void cv::fisheye::stereoRectify (InputArray K1, InputArray D1, InputArray K2, InputArray D2, const Size &imageSize, InputArray R, InputArray tvec, OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags, const Size &newImageSize=Size(), double balance=0.0, double fov_scale=1.0) Stereo rectification for fisheye camera model,鱼眼相机模型的立体校正

六、OpenCV与其他工具联合开发

1、ROS 图像与 OpenCV图像 之间的转换

头文件:cv_bridge/cv_bridge.h,这个头文件主要是我们将使用这个进行图像格式的转换,把opencv的Mat转化ROS的消息格式,或者把ROS格式的消息转化为opencv的Mat。

请点击-> Ros图像与Opencv图像的相互转换cv_bridge(C++) >--------< 附加:ros官网

2、OpenCV与Qt

请点击-> OpenCV使用QT GUI显示

请点击-> Qt+OpenCV联合开发(十九)–鼠标操作与响应

请点击-> OpenCV实现SFM(三):多目三维重建

七、 Eigen相关

1、各个模块介绍

模块名称 头文件 介绍说明
Core #include Matrix and Array classes, basic linear algebra (including triangular and selfadjoint products), array manipulation
Geometry #include Transform, Translation, Scaling, Rotation2D and 3D rotations (Quaternion, AngleAxis)
LU #include Inverse, determinant, LU decompositions with solver (FullPivLU, PartialPivLU)
Cholesky #include LLT and LDLT Cholesky factorization with solver
Householder #include Householder transformations; this module is used by several linear algebra modules
SVD #include SVD decompositions with least-squares solver (JacobiSVD, BDCSVD)
QR #include QR decomposition with solver (HouseholderQR, ColPivHouseholderQR, FullPivHouseholderQR)
Eigenvalues #include Eigenvalue, eigenvector decompositions (EigenSolver, SelfAdjointEigenSolver, ComplexEigenSolver)
Sparse #include Sparse matrix storage and related basic linear algebra (SparseMatrix, SparseVector)
(see Quick reference guide for sparse matrices for details on sparse modules)
#include Includes Core, Geometry, LU, Cholesky, SVD, QR, and Eigenvalues header files
#include Includes Dense and Sparse header files (the whole Eigen library)

请点击-> Eigen: C++开源矩阵计算工具——Eigen的简单用法

请点击-> C++学习笔记——Eigen模块(用于矩阵运算)

请点击-> Eigen介绍及简单使用

2、Eigen函数列表

函数名称 函数说明
Eigen::AngleAxis() Represents a 3D rotation as a rotation angle around an arbitrary 3D axis. 将三维旋转表示为围绕任意三维轴的旋转角度。from官网
所需头文件:#include

3、仿射变换矩阵

Eigen库中,仿射变换矩阵的大致用法为:
创建Eigen::Affine3f 对象a。
创建类型为Eigen::Translation3f 对象b,用来存储平移向量;
创建类型为Eigen::Quaternionf 四元数对象c,用来存储旋转变换;
最后通过以下方式生成最终Affine3f变换矩阵: a=bc.toRotationMatrix();
一个向量通过仿射变换时的方法是result_vector=test_affine
test_vector;

八、相关理论知识(疑惑点)

请点击–> pitch yaw roll是什么

请点击–> opencv 的CV_Assert()函数



九、传感器相关知识

请点击–> 浅析相机FOV

请点击–> 摄像头(相机)焦距和视场角

请点击–> 工业相机与镜头选型方法(含实例)

请点击–> 模型 16个相机参数(内参、外参、畸变参数)

请点击–> 相机基础知识讲解:CMOS和CCD

请点击–> CCD CMOS传感器基本工作原理

摄像头相关名词 名词解释
焦距f 焦距也称为焦长,是光学系统中衡量光的聚集或发散的度量方式,指从透镜中心到光聚集之焦点的距离。亦是照相机中,从镜片光学中心到底片、CCD或CMOS等成像平面的距离。
景深(DOF) 是指在摄影机镜头或其他成像器前沿能够取得清晰图像的成像所测定的被摄物体前后距离范围。光圈、镜头、及焦平面到拍摄物的距离是影响景深的重要因素。在镜头前方(焦点的前、后)有一段一定长度的空间,当被摄物体位于这段空间内时,其在底片上的成像恰位于同一个弥散圆之间。被摄体所在的这段空间的长度,就叫景深。
换言之,在这段空间内的被摄体,其呈现在底片面的影象模糊度,都在容许弥散圆的限定范围内,这段空间的长度就是景深。
弥散圆(circle of confusion) 物点成像时,由于像差,其成像光束不能会聚于一点,在像平面上形成一个扩散的圆形投影,成为弥散圆。当使点光源经过镜头在像平面成像,如果此时保持镜头与像平面距离不变,沿光轴方向前后移动点光源,则像平面上成的像就会成为有一定直径的圆形,就叫弥散圆。 它也被又译为弥散圈、弥散环、散光圈、 模糊圈、 散射圆盘。
镜头焦距、光圈、物距与景深之间的关系 镜头焦距、光圈、物距与景深之间的关系

OpenCV与Eigen (C++)【学习备忘】_第7张图片

你可能感兴趣的:(opencv,自动驾驶)