OpenCV基本的函数整理

头文件两种格式
#include <>
#include “”
Mat srcImage = imread (“1.jpg”); // 载入原图
imshow ("【图像显示】",srcImage); // 显示图像
Mat dstImage ; // 声明Mat类型的变量
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); // 返回指定形状和尺寸的结构元素(内核矩阵),返回Mat类型
ecrod( srcImage, dstImage, element); // 图像腐蚀操作
blur( srclmage , dstlmage , Size (7 , 7) ); // 进行均值滤波操作(图像模糊)7x7内核降噪
dstImage.create(srcImage.size(), srcImage.type()); // 创建与src同类型同大小的矩阵dst
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY); // 将原图像转换为灰度图像
Canny(dstImage, dstImage, 3, 9, 3); // Canny边缘检测
读取并播放视频
读入视频的两种方法
(1)先实例化再初始化
VideoCapture capture ;
capture.open(“1.avi”);
(2)在实例化的同时初始化
VideoCapture capture(“1.avi”); // VideoCapture capture(0) 为调用摄像头采集图像
// 循环显示每一帧
while(1)
{
Mat frame; // 定义一个Mat变量。用于存储每一帧的图像
capture>>frame; // 读取当前帧
imshow(“读取视频”,frame); // 显示当前帧
waitKey(30); // 延时30ms
}
格式输出: printf()函数
int printf(const char format, . . .); // int printf(“格式控制字符串” , 输出表列) ;
显示当前使用的版本:printf ( " \ t 当前使用的OpenCV版本为OpenCV ", CV_VERSION);
Mat类是用于保存图像以及其他矩阵数据的数据结构,默认情况下其尺寸为0。
图像的载入:imread()函数
Mat imread(const string& filename, int flags=1 );
// 参数1:const string& 类型的filename,填入需要载入的图片路径名。Windows操作系统下。OpenCV的imread函数支持如下类型的图像
Windows位图:
.bmp,.dib
JPEG文件:
.jpeg,.jpg,.jpe
JPEG2000文件:.jp2
PNG图片:
.png
便携文件格式:.pbm,.pgm,.ppm
Sun rasters光栅文件:
.sr,.ras
TIFF文件:
.tiff,.tif
// 参数2:载入标识,指定一个加载图像的颜色类型。默认值1,可以忽略,忽略时代表载入三通道的彩色图像。
flags > 0 返回一个3通道的彩色图像
flags = 0 返回灰度图像
flags < 0 返回包含Alpha通道的加载图像
//加载掩膜(必须是灰皮图) Mat mask= imread ("dota_logo . jpg " , 0) ;
图像的显示:imshow()函数
void imshow(const string& winname, InputArray mat);
// 参数1:const string& 类型的winname,填需要显示的窗口标识名称
// 参数2:InputArray类型的mat,填需要显示的图像(暂记为和Mat类相同功能)
创建窗口:namedWindow()函数
void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE);
// 参数1:窗口名称
// 参数2:窗口标识(WINDOW_NORMAL:可改变窗口大小;WINDOW_AUTOSIZE:自适应大小,默认;WINDOW_OPENGL:支持OpenGL)
输出图像到文件:imwrite()函数
bool imwrite(const string& filename, InputArray img, const vector& params=vector() );
// 参数1:需要写入的文件名,要带后缀,如“123.jpg”。
// 参数2:InputArray类型的img,一般填一个Mat类型的图像数据
// 参数3:特定格式保存的参数编码。默认值vector(),一般不需要填写。
imwrite函数用于将图像保存到指定的文件。图像格式是基于文件扩展名的,可保存的扩展名和imread中可以读取的图像扩展名一致。
创建滑动条:createTrackbar()函数
int createTrackbar(const string& trackbarname, const string& winname, int
value, int count, TrackbarCallback onChange=0, void* userdata=0);
// 参数1:轨迹条名字
// 参数2:窗口名字,表示这个轨迹条会依附到哪个窗口上,对应namedWindow()创建窗口时填的某一个窗口名
// 参数3:一个指向整型的指针,表示滑块的位置
// 参数4:表示滑块可以达到的最大位置的值,滑块最小位置的值始终为0
// 参数5:默认值0,指向回调函数的指针,每次滑块位置变化时,这个函数就会进行回调。且这个函数的原型必须是voidXXXX(int, void*);其中第一个
参数是轨迹条的位置,第二个参数是用户数据。如果回调是NULL指针,则表示没有回调函数调用,仅参数3 value有变化。
// 参数6:默认值0,用户传给回调函数的数据,用来处理轨迹条事件。如果使用的参数3 value实参是全局变量的话,可以不管这个userdata参数
获取当前轨迹条的位置: getTrackbarPos()函数
int getTrackbarPos(const string& trackbarname , const string& winname) ;
// 参数1:表示轨迹条的名字。
// 参数2:表示轨迹条的父窗口的名称
Mat 结构的使用
Mat 是一个类, 由两个数据部分组成: 矩阵头(包含矩阵尺寸、存储方法、存储地址等信息〉和一个指向存储所有像素值的矩阵(根据所选存储方法的
不同, 矩阵可以是不同的维数)的指针。
OpenCV 函数中输出图像的内存分配是自动完成的(如果不特别指定的话)。
使用OpenCV 的C++接口时不需要考虑内存释放问题。
赋值运算符和拷贝构造函数(构造函数)只复制信息头。
使用函数clone()或者copyTo()来复制一幅图像的矩阵。
显式创建Mat 对象的七种方法

  1. 【方法一】使用Mat()构造函数
    Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255) );
    对于二维多通道图像,首先要定义其尺寸,即行数和列数。然后, 需要指定存储元素的数据类型以及每个矩阵点的通道数。为此,依据下面的规则有
    多种定义: CV_[The number of bits per item] [Signed or Unsigned] [Type Prefix]C[The channel number]
    即 : CV_[位数][带符号与否][类型前缀]C[通道数]
    比如CV_8UC3 表示使用8 位的unsigned char 型,每个像素由三个元素组成三通道。
  2. 【方法二】在C\C++ 中通过构造函数进行初始化
    int sz[3] = {2, 2, 2};
    Mat L(3, sz, CV_8UC, Scalar::all(0) );
    上面的例子演示了如何创建一个超过两维的矩阵: 指定维数,然后传递一个指向一个数组的指针, 这个数组包含每个维度的尺寸; 后续的两个参数与
    方法一中的相同。
  3. 【方法三】为己存在的Ipllmage 指针创建信息头
    Ipllmage* img = cvLoadImage(“1.jpg”, 1);
    Mat mtx(img); // 转换Ipllmage* -->Mat
    4 . 【方法四】利用Create()函数
    方法四是利用Mat 类中的Create()成员函数进行Mat 类的初始化操作,示范代码如下。
    M. create(4 , 4 , CV_8UC(2)) ;
    cout << "M = "<< endl << " " << M << endl << endl ;
    需要注意的是, 此创建方法不能为矩阵设初值, 只是在改变尺寸时重新为矩阵数据开辟内存而己。
  4. 【方法五】采用Matlab 式的初始化方式
    方法五采用Matlab 形式的初始化方式: zeros() . ones(), eyes() 。使用以下方式指定尺寸和数据类型:
    Mat E = Mat::eye(4, 4, CV_64F);
    cout << "E = " << endl << " " << E << endl << endl;
    Mat O = Mat::ones(2, 2,CV_32F);
    cout << "O = " << endl << " " << O << endl << endl;
    Mat Z = Mat::zeros(3, 3,CV_8UC1);
    cout << "Z = " << endl << " " << Z << endl << endl;
    6 . 【方法六】对小矩阵使用逗号分隔式初始化函数
    方法六为对小矩阵使用逗号分隔式初始化函数, 示范代码如下。
    Mat C = (Mat_ (3 , 3) << 0 , - 1 , 0, -1, 5, -1, 0, -1 , 0) ;
    cout << "C = " << endl << " " << C << endl << endl ;
    7 . 【方法七】为己存在的对象创建新信息头
    方法七为使用成员函数clone()或者copyTo()为一个己存在的Mat 对象创建一个新的信息头,示范代码如下:
    Mat RowClone = C. row(l).clone() ;
    cout << "RowClone = " << endl << " " << RowClone << endl << endl ;
    点的表示: Point 类
    颜色的表示: Scalar 类
    尺寸的表示: Size 类
    矩形的表示: Rect 类
    颜色空间转换: cvtColor()函数
    基本图形的绘制
    · 用于绘制直线的line 函数;
    · 用于绘制椭圆的ellipse 函数:
    . 用于绘制矩形的rectangle 函数;
    . 用于绘制圆的circle 函数;
    · 用于绘制填充的多边形的fillPoly 函数。
    计时函数
    另外有个问题是如何计时。可以利用这两个简便的计时函数——getTickCount()和getTickFrequency() 。
    • getTickCount() 函数返回CPU 自某个事件(如启动电脑) 以来走过的时钟周期数
    • getTickFrequency() 函数返回CPU 一秒钟所走的时钟周期数。这样,我们就能轻松地以秒为单位对某运算计时。
    这两个函数组合起来使用的示例如下。
    double time0 = static_cast (getTickCount ()) ; // 记录起始时间
    // 进行图像处理操作…
    time0 = ( (double)getTickCount() - time0)/getTickFrequency ( ) ;
    cout<< " 此方法运行时间为: " <<time0 << “秒”<<endl ; / /输出运行时间
    感兴趣区域: ROI
    定义ROl 区域有两种方法:
    //方法一
    imageROI=image(Rect(500 , 250 , logo.cols , logo.rows));
    // 方法二
    imageROI=image(Range(250 , 250+logoImage.rows) , Range(200 , 200+logoImage. cols) ) ;
    计算数组加权和: addWeighted ()函数
    这个函数的作用是计算两个数组(图像阵列)的加权和。原型如下:
    void (InputArray src1 , double alpha , InputArray src2 , double beta, double gamma , OutputArray dst , int dtype=-1);
    · 第一个参数, lnputArray 类型的src1 , 表示需要加权的第一个数组,常常填一个Mat;
    . 第二个参数, double 类型的alpha , 表示第一个数组的权重:
    · 第三个参数, lnputArray 类型的src2 , 表示第二个数组, 它需要和第一个数组拥有相同的尺寸和通道数;
    · 第四个参数, double 类型的beta , 表示第二个数组的权重值;
    · 第五个参数, double 类型的gamma , 一个加到权重总和上的标量值。其含义通过接下来列出的式子自然会理解:
    · 第六个参数, OutputArray类型的dst ,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数;
    · 第七个参数, int 类型的dtype ,输出阵列的可选深度, 有默认值-1 。当两个输入数组具有相同的深度时,这个参数设置为-1 (默认值) ,
    即等同src1.depth()。
    通道分离: split()函数
    split 函数用于将一个多通道数组分离成几个单通道数组
    这个split 函数的C++版本有两个原型, 分别是:
    • C ++: void split( const Mat& src, Matmvbegin);
    • C++ : void split(InputArray m ,OutputArrayOfArrays mv);
    变量介绍如下:
    · 第一个参数, InputArray 类型的m 或者const Mat&类型的src ,填我们需要进行分离的多通道数组。
    · 第二个参数,OutputArrayOfArrays 类型的mv , 填函数的输出数组或者输出的vector 容器。
    通道合并: merge()函数
    merge() 函数是split() 函数的逆向操作将多个数组合并成一个多通道的数组。它通过组合一些给定的单通道数组,将这些孤立的单通道数组合并成
    一个多通道的数组,从而创建出一个由多个单通道阵列组成的多通道阵列。它有两个基于C++的函数原型如下。
    • C++: void merge(const Mat
    mv, size_tcount, OutputArray dst)
    • C++: void merge( InputArrayOfArrays mv,OutputArray dst)
    变量介绍如下。
    · 第一个参数, mv 。填需要被合并的输入矩阵或vector 容器的阵列,这个mv 参数中所有的矩阵必须有着一样的尺寸和深度。
    · 第二个参数, count。当mv 为一个空白的C 数组时,代表输入矩阵的个数,这个参数显然必须大于1 。
    · 第三个参数, dst。 即输出矩阵,和mv[0]拥有一样的尺寸和深度,并且通道的数量是矩阵阵列中的通道的总数。
    根据OpenCV 的BGR 色彩空间( Bule 、Green 、Red,蓝绿红), 其中channels.at(0)就表示引用取出channels 中的蓝色分量,channels.at(1)
    就表示引用取出channels中的绿色分量, channels.at(2)就表示引用取出channels 中的红色分量。
    离散傅里叶变换
    离散傅里叶变换(Discrete Fourier Transform ,缩写为DFT ) ,是指傅里叶变换在时域和频域上都呈现离散的形式, 将时域信号的采样变换为在
    离散时间傅里叶变换(DTFT) 频域的采样。
    dft()函数详解
    dft()函数的作用是对一维或二维浮点数数组进行正向或反向离散傅里叶变换。
    C++: void dft(InputArray src , OutputArray dst , int flags=0 , int nonzeroRows=0)
    · 第一个参数, InputArray 类型的src。 输入矩阵,可以为实数或者虚数。
    · 第二个参数, OutputArray 类型的dst。函数调用后的运算结果存在这里,其尺寸和类型取决于标识符,也就是第三个参数flags。
    · 第三个参数, int 类型的flags 。转换的标识符,有默认值0。
    · 第四个参数, int 类型的nonzeroRows ,有默认值0 。当此参数设为非零时(最好是取值为想要处理的那一行的值,比如C . rows ) ,函数会假设
    只有输入矩阵的第一个非零行包含非零元素(没有设置DFT_lNVERSE 标识符) ,或只有输出矩阵的第一个非零行包含非零元素(设置了DFT_lNVERSE标
    识符)。这样的话,函数就可对其他行进行更高效的处理,以节省时间开销。
    返回DFT 最优尺寸大小: getOptimalDFTSize()函数
    getOptimaIDFTSize 函数返回给定向量尺寸的傅里叶最优尺寸大小。为了提高离散傅里叶变换的运行速度,需要扩充图像,而具体扩充多少,就由
    这个函数来计算得到。
    C++: int getOptimalDFTSize(int vecsize )
    此函数的唯一一个参数为int 类型的vecsize ,向量尺寸,即图片的rows 、cols 。
    扩充图像边界: copyMakeBorder()函数
    copyMakeBorder 函数的作用是扩充图像边界。
    voìd copyMakeBorder(InputArray src, OutputArray dst , int top , int bottom, int left, int right, int borderType, const Scalar& value=Scalar())
    · 第一个参数, lnputArray 类型的src ,输入图像,即源图像, 填Mat 类的对象即可。
    · 第二个参数, OutputArray 类型的dst ,函数调用后的运算结果存在这里,即这个参数用于存放函数调用后的输出结果, 需和源图片有一样的尺寸
    和类型,且size 应该为Size ( src.cols+left+right, src.rows+top+ bottom ) 。
    · 接下来的4 个参数分别为int 类型的top 、bottom 、left、right ,分别表示在源图像的四个方向上扩充多少像素,例如top=2,bottom=2 ,
    left=2 ,right=2就意味着在源图像的上下左右各扩充两个像素宽度的边界。
    · 第七个参数, borderType 类型的,边界类型, 常见取值为BORDER_CONSTANT ,可参考borderInterpolate()得到更多的细节。
    · 第八个参数, const Scalar&类型的value ,有默认值Scalar() ,可以理解为默认值为0 。当borderType 取值为BORDER_CONSTANT 时,这个参数
    表示边界值。
    计算二维矢量的幅值: magnitude()函数
    magnitude() 函数用于计算二维失量的幅值。
    C++ : void magnitude(InputArray x, InputArray y, OutputArray magnitude)
    . 第一个参数, InputArray类型的x,表示矢量的浮点型X坐标值,也就是实部。
    · 第二个参数, InputArray类型的y,表示矢量的浮点型Y坐标值,也就是虚部。
    · 第三个参数, OutputArray类型的magnitude,输出的幅值,它和第一个参数x 有着同样的尺寸和类型。
    计算自然对数: log()函数
    log()函数的功能是计算每个数组元素绝对值的自然对数。
    C++ : void log (InputArray src , OutputArray dst )
    第一个参数为输入图像, 第二个参数为得到的对数值。
    矩阵归一化: normalize()函数
    void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() )
    · 第一个参数, InputArray 类型的src 。输入图像, 即源图像,填Mat 类的对象即可。
    · 第二个参数, OutputArray 类型的dst 。函数调用后的运算结果存在这里,和源图片有一样的尺寸和类型。
    · 第三个参数, double 类型的alpha 。归一化后的最大值, 有默认值1 。
    . 第四个参数, double 类型的beta 。归一化后的最大值, 有默认值0 。
    · 第五个参数, int 类型的norm_type 。归一化类型, 有NORM_INF、NORM_L1 、NORM_L2 和NORM_MINMAX 等参数可选,有默认值NORM_L2 。
    · 第六个参数, int 类型的dtype, 有默认值-1 。当此参数取负值时,输出矩阵和src有同样的类型,否则,它和I src有同样的通道数, 且此时图像深度为
    CV_MAT_DEPTH (dtype) 。
    · 第七个参数,InputArray 类型的mask ,可选的操作掩膜, 有默认值noArray() 。
    FileStorage 类操作文件

(未完待续……)