OpenCV and Eigen (C++) [study notes]



Clickable OpenCV comes from the short book /// The unit in OpenCV on the OpenCV official website Checkerboard side length size: mm 【Machine Vision】


OPENCV

1. Introduction to each module

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】: In fact, it is the combined abbreviation of Calibration (calibration) and 3D. This module is mainly related to camera calibration and 3D reconstruction. Basic multi-view geometry algorithm, single stereo camera calibration, object pose estimation, stereo similarity algorithm, 3D information reconstruction, etc.
[contrib]: It is the abbreviation of Contributed/Experimental Stuf. This module contains some recently added optional functions that are not stable, so there is no need to worry about it. After 2.4.8, there will be new face recognition, stereo matching, artificial retina model and other technologies.
[core]: Core function modules, especially the underlying data structure and algorithm functions. Contains the following:

(1) OpenCV basic data structure
(2) Dynamic data structure
(3) Drawing functions
(4) Functions related to array operations
(5) Auxiliary functions and system functions and macros

[imgproc]: The abbreviation combination of the words Image and Processing. Image processing module, this module contains the following content:

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

【features2d】: d is Features2D, a 2D functional framework, including POI detectors, descriptors, and POI matching frameworks. Contains the following:

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

[flann]: Fast Library for Approximate Nearest Neighbors, a high-dimensional approximate nearest neighbor fast search algorithm library, contains two parts: fast approximate nearest neighbor search and clustering.
[gpu]: A computer vision module that uses GPU acceleration.
【highgui】: That is, high gui, high-level GUI graphical user interface, including media I/O input and output, video capture, image and video encoding and decoding, interface of graphical interactive interface, etc.
【legacy】: Some obsolete code bases are reserved for backward compatibility.
[ml]: Machine Learning, machine learning module, basically statistical model and classification algorithm, including the following content:

(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]: That is, some patented algorithm modules, including feature detection and GPU-related content. It is best not to use it commercially, you may be sued.
[objdetect]: Object detection module, including Cascade Classification (cascade classification) and Latent SVM.
[ocl]: That is, OpenCL-accelerated Computer Vision, which uses OpenCL-accelerated computer vision component modules.
【photo】: Computational Photography, including image restoration and image denoising.
【stitching】: images stitching, image stitching module, including the following parts:

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

[superres]: SuperResolution, related functional modules of super-resolution technology.
[ts]: opencv test related code, don't worry about it.
[video]: Video analysis component, this module includes motion estimation, background separation, object tracking and other video processing related content.
【Videostab】: Video stabilization, components related to video stabilization.

2. Data types and class objects

1. Data type (point class, size class, vector class, rectangle class, pointer class, exception class, etc.)

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

1.1 cv::Point class

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

1.2 cv::Size class

For details, see the Size data structure, please click

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

1.3 cv::Scalar class

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

1.4 cv::Rect class

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

1.5 cv::RotatedRect class

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

1.6 Fixed matrix classes

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

1.7 Fixed vector classes

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

1.8 Complex numbers

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

1.9 Auxiliary object - cv::TermCriteria class

确定算法的终止条件。
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.10 Auxiliary object - cv::Range class

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

1.11 Helper objects - cv::Ptr templates and garbage collection

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

1.12 Auxiliary objects - cv::Exception class and exception handling

请添加

1.13 Auxiliary object - cv::DataType<> template

请添加

2. Class object

2.1 Interface class

2.1.1 InputArray or OutputArray interface class

InputArray这个接口类可以是Mat、Mat_<T>、Mat_<T, m, n>、vector<T>、vector<vector<T>>、vector<Mat>。也就意味着当你看refman或者源代码时,如果看见函数的参数类型是InputArray型时,把上诉几种类型作为参数都是可以的。有时候InputArray输入的矩阵是个空参数,你只需要用cv::noArray()作为参数即可,或者很多代码里都用cv::Mat()作为空参。这个类只能作为函数的形参参数使用,不要试图声明一个InputArray类型的变量。如果在你自己编写的函数中形参也想用InputArray,可以传递多类型的参数,在函数的内部可以使_InputArray::getMat()函数将传入的参数转换为Mat的结构,方便你函数内的操作;必要的时候,可能还需要_InputArray::kind()用来区分Mat结构或者vector<>结构,但通常是不需要的。

3. Mat (matrix) in OpenCV

1. Create and initialize the matrix

Please click –> 【OpenCV3】Definition and initialization of cv::Mat
Please click –> Detailed explanation and usage of OpenCV Mat class

补充:创建矩阵
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());

To establish a matrix, you must specify the data type stored in the matrix. Several data types commonly used in image processing are as follows:

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通道
!!!!!强调:数组中的数据是按行连续组织的,因此不可以通过这种方式去访问一个指定的列。

Data type of matrix elements:

C1 C2 C3 C4
CV_8U 0 8 16 24
CV_8S 1 9 17 25
CV_16U 2 10 18 26
CV_16S 3 11 19 27
CV_32S 4 12 20 28
CV_32F 5 13 21 29
CV_64F 6 14 22 30

C1, C2, C3, and C4 in the header refer to the number of channels (Channel). For example, a grayscale image has only one channel, which is C1; an RGB color image in JPEG format has 3 channels, which is C3; a color image in PNG format In addition to the RGB 3 channels, there is also a transparency channel, so it is C4. You will also find out why 7 is not defined as a type. This can be seen in the OpenCV source code. There is a line as shown below, indicating that 7 is used to customize for users:

#define CV_USRTYPE1 7

If it is just to clarify the data type before numerical calculation, then you can see here; if you want to use the at method to access data elements, then you need the next step. Because taking a single channel as an example, the at method accepts a data type such as uchar instead of CV_8U. Given the number of channels and the data type of each channel, the data types assigned to the at method are shown in the table below:

C1 C2 C3 C4 C6
fly fly cv::Vec2b cv::Vec3b cv::Vec4b
short short cv::Vec2s cv::Vec3s cv::Vec4s
int int cv::Vec2i cv::Vec3i cv::Vec4i
float float cv::Vec2f cv::Vec3f cv::Vec4f cv::Vec6f
double double cv::Vec2d cv::Vec3d cv::Vec4d cv::Vec6d
cv::Vec3b vec3b = img.at<cv::Vec3b>(0,0);
uchar vec3b0 = img.at<cv::Vec3b>(0,0)[0];
uchar vec3b1 = img.at<cv::Vec3b>(0,0)[1];
uchar vec3b2 = img.at<cv::Vec3b>(0,0)[2];
std::cout << "vec3b = " << vec3b << std::endl;
std::cout << "vec3b0 = " << (int)vec3b0 << std::endl;
std::cout << "vec3b1 = " << (int)vec3b1 << std::endl;
std::cout << "vec3b2 = " << (int)vec3b2 << std::endl;

2. cv::Mat function list

cv::Mat function (full) name describe
cv::Mat::reshape() The reshape function can change the number of channels and serialize matrix elements
cv::Mat::isContinuous() Return bool value, judge whether the storage is continuous, if there is no gap between the rows of the matrix, return true
cv::Mat::clone() m1 = m0.clone();
copy m0 completely to m1, copy all the data in m0 at the same time, and the copied matrix is ​​continuous.
cv::Mat::convertTo() void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
mainly based on the formula dst = alpha * src + beta (alpha controls contrast, beta controls brightness)
m0.convertTo(m1, type, alpha , beta); Type conversion, but not the number of channels.
Convert the elements in m0 to a type class (CV_32F, etc.).
Contrast brightness image enhancement and convertTo detailed explanation
cv::Mat::push_back() m0.push_back(s); //Extend the mx1 matrix and insert a single value s at the end.
m0.push_back(m1); //Extend the matrix m0 with size mxn to k rows, and copy m1 to these rows; the size of m1 must be kxn.
cv::Mat::pop_back() m0.pop_back(n); //Remove n lines from the end of m0, n is 1 by default.
cv::Mat::type() m0.type(); //Returns the effective type identifier of the elements in m0 (such as CV_32FC3).
cv::Mat::depth() m0.depth(); // Returns the effective type identifier (such as CV_32F) for elements in a single channel in m0.
cv::Mat::channels() m0.channels(); //Returns the channel number of elements in m0.
cv::Mat::size() m0.size(); //Return the size of m0 in the form of cv::Size object.
cv::Mat::empty() m0.empty(); //Returns true if there are no elements in the array (such as m0.total == 0 or m0.data == NULL).
cv::Mat::ptr Common form: mat.ptr(row)[col] For the ptr function of Mat, the template type pointer in <> is returned, pointing to the starting point of row row in (), usually the type in <> is the same as Mat The element types should be the same, and then use the pointer to access the element corresponding to the col column position
cv::Mat::inv( method ) Find the inverse matrix of the matrix. There are three methods: cv::DECOMP_LU (default), cv::DECOMP_CHOLESKY, cv::DECOMP_SVD.
cv::Mat::cross() Computes a cross product of 3-element vectors. Only works for 3×1 matrices
cv::Mat::dot() Computes the dot product of two vectors.
cv::Mat::mul() Calculate the product of the corresponding bits of two Mat matrices, so the number of rows and columns of the matrix A involved in the operation is the same as the number of rows and columns of B.
Function prototype: C++: MatExpr Mat::mul(InputArray m, double scale=1) const.
Usage: Mat AB=A.mul(B);
cv::Mat::t() Matrix transpose operation
cv::Mat::rowRange() && cv::Mat::colRange() rowRange creates a new matrix header for the specified row span, which can take the specified row interval elements; colRange creates a new matrix header for the specified column span, and can take the specified column interval elements. from official website
cv::Mat::
cv::Mat::
cv::Mat::
cv::Mat::
cv::Mat::
cv::Mat::
cv::UMat It has most of the similar functions and the same API functions as Mat. By using the UMat object, OpenCV will automatically use GPU computing on devices that support OpenCL, and still use CPU computing on devices that do not support OpenCL, thus avoiding program failures , and unified the interface.

3. Obtain array elements independently (access)

Please click -> cv::Mat pixel traversal method (3 types)

Please click -> to access the value of each pixel in the 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通道等特性。

3、svg

SVG是一种用XML定义的语言,用来描述二维矢量及矢量/栅格图形。它具有现在网络流行的PNG和JPEG格式无法具备的优势:可以任意放大图形显示,但绝不会以牺牲图像质量为代价;可在SVG图像中保留可编辑和可搜寻的状态;平均来讲,SVG文件比JPEG和PNG格式的文件要小很多,因而下载也很快。可以相信,SVG的开发将会为Web提供新的图像标准。

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

(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等格式图像大小会有差异,这个知道就行,不进行深度分析。

6、视频流

请点击-> 基于OpenCV的网络实时视频流传输
请点击-> 计算机视觉——利用openCV与Socket结合进行远程摄像头实时视频传输并保存图片数据

四、图像变换相关内容

1、变换

1.1透视变换

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

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

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

1.2 重映射

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

2、相机

2.1 相机内参矩阵

请点击–> 相机内参矩阵 ( Camera Matrix )
请点击–> 针孔相机模型和相机内参矩阵K
相机的内参是:1/dx、1/dy、r、u0、v0、f
opencv相机内参矩阵K:

内参矩阵K包括5个未知参数。一般情况下,摄像机倾斜因子s=0。因此K就只有4个未知参数了,分别为fx、fy、u0(cx)、v0(cy)。其实opencv中的fx也就是F*Sx,其中F是焦距上面的f,Sx是像素/每毫米也就是上面的1/dx。
在这里插入图片描述

在这里插入图片描述

2.2 相机畸变参数

畸变参数是:k1,k2,k3 径向畸变系数,p1,p2是切向畸变系数。
2.2.1 径向畸变
径向畸变发生在相机坐标系转像物理坐标系的过程中。径向畸变又分为正向畸变和负向畸变,正向畸变称为枕形畸变,负向畸变称为桶形畸变。
枕形畸变(Pincushion Distortion)又称枕形失真,它是指光学系统引起的成像画面向中间“收缩”的现象。枕形畸变在长焦镜头成像时较为常见。使人变瘦高的哈哈镜成像属于枕型畸变。
桶形畸变 (Barrel Distortion)又称桶形失真,是指光学系统引起的成像画面呈桶形膨胀状的失真现象。桶形畸变在摄影镜头成像尤其是广角镜头成像时较为常见。使人变矮胖的哈哈镜成像是桶型畸变的一个比较形象的例子。

在这里插入图片描述
2.2.2 切向畸变
切向畸变:产生的原因是透镜不完全平行于图像。

2.3 相机外参

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

位姿求解方法

方法 概念解释
对极约束 2D-2D,通过二维图像点的对应关系,恢复两帧之间相机的运动。
PnP 3D-2D,求解3D到2D点对运动的方法。已知3D空间点及其在相机投影位置时,求解相机运动。
ICP 3D-3D,配对好的3D点,已知世界坐标系下的3D点和相机坐标系下的3D点。
NDT

请点击–> 像素坐标转到世界坐标时相机坐标系中的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;

一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达

PnP(Perspective-n-Point)问题就是在已知世界坐标系下N个空间点的真实坐标以及这些空间点在图像上的投影,如何计算相机所在的位姿。

外参求解函数: cv::solvePnP()

flags 名词解释及要点
(默认)SOLVEPNP_ITERATIVE = 0 适合点在同一平面上的情况。该方法基于Levenberg-Marquardtoptimization(列文伯格-马夸尔特算法)迭代求解PNP问题,实质是迭代求出重投影误差最小的解,这个解显然不一定是正解。迭代法调用cvFindExtrinsicCameraParams2,进而使用SVD分解并调用cvFindHomography,而cvFindHomography需要至少4组点。
SOLVEPNP_EPNP = 1 需要4对不共面的(对于共面的情况只需要3对)3D-2D匹配点,是目前最有效的PnP求解方法。深入EPnP算法
SOLVEPNP_P3P = 2 P3P只使用4组点,3组求出多个解,第四组确定最优解
SOLVEPNP_DLS = 3 opencv3版本的算法当前是不稳定的,至少四点不在同一平面
SOLVEPNP_UPNP = 4 opencv3版本的算法当前是不稳定的
SOLVEPNP_AP3P = 5 AP3P只使用4组点,3组求出多个解,第四组确定最优解
SOLVEPNP_IPPE = 6 输入点必须 >= 4 并且对象点必须共面
SOLVEPNP_IPPE_SQUARE = 7 适用于标记姿势估计的特殊情况。 输入点数必须为 4。对象点必须按顺序定义。
SOLVEPNP_SQPNP = 8

2.4 相机模型

请点击–> 相机模型–针孔相机投影(pinhole camera model)
请点击–> 相机模型-鱼眼模型(fisheye camera model)
请点击–> 相机模型-鱼眼模型/Omnidirectional Camera(1)
请点击–> 相机模型-鱼眼模型/鱼眼镜头标定基本原理及实现(2)
在这里插入图片描述

3、旋转变换

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

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

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

5、标定相关

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

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

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

请点击–> 张正友标定算法原理详解
相机标定的目的:
1、相机标定的第一个目的就是获得相机的内参矩阵和外参矩阵。
2、相机标定的第二个目的就是获得相机的畸变参数,进而对拍摄的图片进行去畸变处理。

5.1 双目标定

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

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

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

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

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

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

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

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

在这里插入图片描述
图1. 双摄像头模型俯视图

图2, 双摄像头模型立体视图

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

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 相机校正过程中,calibrateCamera函数projectPoints函数的重投影误差的分析
请点击–> 相机标定(1)内\外参矩阵和畸变矩阵

五、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::initUndistortRectifyMap() Computes the undistortion and rectification transformation map. [ from官网 ]
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像素之间。
void cv::undistortImage
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 <opencv2/opencv.hpp>
cv::find4QuadCornerSubpix ( InputArray img, InputOutputArray corners, Size region_size) 找到棋盘角的亚像素精确位置。作用同cornerSubPix()函数
返回值为bool类型
所需头文件:#include <opencv2/opencv.hpp>
cv::drawChessboardCorners() 用于绘制棋盘格角点的函数
所需头文件:#include <opencv2/opencv.hpp>
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向量转化为旋转矩阵,反之亦然。
cv::solvePnP 函数中参数flags( 三个flags区别(非官方) ):
(1) cv::ITERATIVE( flags=0 ) :
(2)cv::P3P( flags=2 ):
(3)cv::EPNP( flags=1 ):
(1)默认值,它通过迭代求出重投影误差最小的解作为问题的最优解(似乎只能使用共面的四个特征点求位姿)。
(2)是使用非常经典的Gao的P3P问题求解算法。(3)使用文章《EPnP: Efficient Perspective-n-Point Camera Pose Estimation》中的方法求解。
bool cv::solvePnPRansac() cv::solvePnP的一个缺点是对异常值不够鲁棒(针对棋盘格相机标定影响不大)。
cv::findHomography(InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray(), const int maxIters=2000, const double confidence=0.995) Finds a perspective transformation between two planes,得到H单应矩阵。单应矩阵的推导与理解(R, t, {n,d})
cv::decomposeHomographyMat (InputArray H, InputArray K, OutputArrayOfArrays rotations, OutputArrayOfArrays translations, OutputArrayOfArrays normals) 用法来自CSDN,Decompose a homography matrix to rotation(s), translation(s) and plane normal(s) ,分解单应矩阵H得到旋转向量、平移向量、平面法向量。
cv::filterHomographyDecompByVisibleRefpoints(InputArrayOfArrays rotations, InputArrayOfArrays normals, InputArray beforePoints, InputArray afterPoints, OutputArray possibleSolutions, InputArray pointsMask=noArray()) 用法来自CSDN,Filters homography decompositions based on additional information,过滤得到我们想要的旋转向量和平移向量。
void cv::Rodrigues ( InputArray src, //输入旋转向量or矩阵
OutputArray dst, //输出旋转矩阵or向量
OutputArray jacobian = noArray() )
将旋转矩阵转换为旋转向量,反之亦然(from官网)
cv::cv2eigen()
cv::eigen2cv();
这两个函数都要输入两个参数,第一个参数为输入的矩阵,第二个参数为输出的矩阵。
所需头文件:#include <Eigen/Dense>
#include <opencv2/core/eigen.hpp>
#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官网)
WINDOW_NORMAL or WINDOW_AUTOSIZE
WINDOW_FREERATIO or WINDOW_KEEPRATIO
WINDOW_GUI_NORMAL or WINDOW_GUI_EXPANDED
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 <opencv2/calib3d.hpp>
cv::Mat cv::estimateAffine2D() Computes an optimal affine transformation between two 2D point sets. from-opencv官网 表示的是六自由度的仿射变换
所需头文件: #include <opencv2/calib3d.hpp>
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 算法
void cv::findContours() 此函数寻找图像中物体的轮廓。
void cv::drawContours()
cv::VideoCapture 类 视频的获取操作。VideoCapture 类基础知识
OpenCV中使用类VideoCapture加载视频和打开摄像头

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

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

(等距投影模型)cv::fisheye相关函数from官网 描述
cv::getOptimalNewCameraMatrix() + cv::fisheye::initUndistortRectifyMap() + cv::remap() 需包含头文件:#include <opencv2/calib3d.hpp>
结果等同于下面的函数(此搭配效果较优)
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) 共4个参数,由于鱼眼相机的径向畸变非常严重,所以鱼眼相机主要的是 考虑径向畸变,而忽略其余类型的畸变。
参数: 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 <Eigen/Core> Matrix and Array classes, basic linear algebra (including triangular and selfadjoint products), array manipulation
Geometry #include <Eigen/Geometry> Transform, Translation, Scaling, Rotation2D and 3D rotations (Quaternion, AngleAxis)
LU #include <Eigen/LU> Inverse, determinant, LU decompositions with solver (FullPivLU, PartialPivLU)
Cholesky #include <Eigen/Cholesky> LLT and LDLT Cholesky factorization with solver
Householder #include <Eigen/Householder> Householder transformations; this module is used by several linear algebra modules
SVD #include <Eigen/SVD> SVD decompositions with least-squares solver (JacobiSVD, BDCSVD)
QR #include <Eigen/QR> QR decomposition with solver (HouseholderQR, ColPivHouseholderQR, FullPivHouseholderQR)
Eigenvalues #include <Eigen/Eigenvalues> Eigenvalue, eigenvector decompositions (EigenSolver, SelfAdjointEigenSolver, ComplexEigenSolver)
Sparse #include <Eigen/Sparse> Sparse matrix storage and related basic linear algebra (SparseMatrix, SparseVector)
(see Quick reference guide for sparse matrices for details on sparse modules)
#include <Eigen/Dense> Includes Core, Geometry, LU, Cholesky, SVD, QR, and Eigenvalues header files
#include <Eigen/Eigen> 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 <Eigen/Geometry>

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) 物点成像时,由于像差,其成像光束不能会聚于一点,在像平面上形成一个扩散的圆形投影,成为弥散圆。当使点光源经过镜头在像平面成像,如果此时保持镜头与像平面距离不变,沿光轴方向前后移动点光源,则像平面上成的像就会成为有一定直径的圆形,就叫弥散圆。 它也被又译为弥散圈、弥散环、散光圈、 模糊圈、 散射圆盘。
镜头焦距、光圈、物距与景深之间的关系 镜头焦距、光圈、物距与景深之间的关系

在这里插入图片描述

Guess you like

Origin blog.csdn.net/expert_joe/article/details/122521168