目录
5.5.1、dft函数对数组进行傅里叶变换:void dft(IinputArray src,OutputArray dst,int flags=0; int nonzeroRows=0):
5.5.3、返回DFT最优尺寸大小:getOptimalDFTSize(int vecsize):扩充图像,参数为向量尺寸,图像的行数列数
5.5.5、计算二维矢量的幅值:magnitude(InputArray x, InputArray y, OutputArray magnitude):
5.5.6、计算自然对数:log(InputArray src, OutputArray dst)
-
5.1、访问图像中的像素
-
5.1.1、图像在内存中的存储方式
- opencv中通道顺序是BGR,可以使用isContinuous判断矩阵是否是连续存储的
-
5.1.2、颜色空间缩减
- 将现有颜色空间值除以某个输入值,以获得较少的颜色数。比如颜色值0-9取新值0,10-19取10
- int类型除法操作会自动截余
- 1、遍历图像矩阵的每一个像素,2、对像素应用截余公式
- 对于较大的图像,有效的方法是预先计算所有可能的值,然后简要这些值的时候,利用查找表直接赋值即可,查找表是一维或多维数组,存储了不同输入值所对应的输出值,其优势在于只需读取、无需计算
-
5.1.3、LUT函数:look up table操作
- 用于批量进行图像元素查找、扫描和操作图像。
-
5.1.4、计时函数
- getTickCount()函数返回CPU自某个事件(如启动电脑)以来走过的时钟周期数
- getTickFrequency()函数返回CPU一秒钟所走的时钟周期数,就能轻松的以秒为单位对某运算计时
double time0=static_cast<double> (getTickCount()))
记录起始时间time0 = ((double)getTickCount() - time0)/getTickFrequency();
cout<<time0
输出运行时间
-
5.1.5、访问图像中像素的三类方法
- 指针访问
- 迭代器访问
- 动态地址访问
- 主函数
-
-
5.2、ROI区域图像叠加和图像混合
-
5.2.1、感兴趣区域:ROI
- 1、使用表示矩形区域的Rect。(前两个参数表示指定矩形的左上角坐标,后两个参数表示矩形的长宽):
imageROI= image(Rect(500,250,图像.cols,图像.rows))
- 2、指定感兴趣行或列的范围(Range)。Range是指从起始索引到终止索引(不包括终止索引)的一连段连续序列。cRange可以用来定义Range,:
imageROI= image(range(250,250+图像.rows),Range(200,+200+图像.cols))
- 实例程序
- 1、使用表示矩形区域的Rect。(前两个参数表示指定矩形的左上角坐标,后两个参数表示矩形的长宽):
-
5.2.2、线性混合操作
- 线性混合操作是一种典型的二元的像素操作。addWeighted函数
-
5.2.3、计算数组加权和:addWeighted函数
void (InputArray src1,double alpha, InputArray src2, double beta, double gamma,OutputArray dst, int dtype=-1)
:- 第一个参数:需要加权的第一个数组,填一个Mat
- 第二个参数:第一个数组的权重
- 第三个参数:需要加权的第二个数组,与第一个数组拥有相同的尺寸和通道数
- 第四个参数:第二个数组的权重
- 第五个参数:一个加到权重总和上的标量值,
- 第六个参数:输出的数组
- 第七个参数:输出阵列的可选深度,默认值-1;当两个输入数组具有相同的深度时为-1
dst = src1[I]*alpha + src2[I]*beta+gamma
:计算两个数组的加权和,得到结果输出给第五个参数,I 表示数组元素的索引。遇到多通道数组的时候,每个通道需要独立的进行处理。
-
-
5.3、分离颜色通道、多通道图像融合
-
5.3.1 通道分离:split()函数
- 将一个多通道数组分离成几个单通道数组
void split(const Mat& src,Mat *mvbegin)
void split(InputArray m, OutputArrayOfArrays mv)
- 第一个参数,填需要分离的多通道数组
- 第二个参数,填函数的输出数组或vector容器
-
5.3.2、通道合并:merge()函数
void merge(const Mat*mv,size_tcount,OutputArray dst)
void merge(InputArrayOfArray mv,OutputArray dst)
- 第一个参数:需要被合并的输入矩阵,
- 第二个参数:输入矩阵的个数
- 第三个参数:输出矩阵
- 多通道融合:
-
-
5.4、图像对比度、亮度值调整
- 5.4.1、
- 5.4.1、
-
5.5、离散傅里叶变换
-
5.5.1、dft函数对数组进行傅里叶变换:
void dft(IinputArray src,OutputArray dst,int flags=0; int nonzeroRows=0)
:- 第一个参数:输入矩阵
- 第二个参数:结果矩阵,其尺寸和类型取决于第三个参数
- 第三个参数:
- 第四个参数:为0时,函数会假设只有输入矩阵的第一个非零行包含非零元素。
-
5.5.3、返回DFT最优尺寸大小:getOptimalDFTSize(int vecsize):扩充图像,参数为向量尺寸,图像的行数列数
-
5.5.4、扩充图像边界:copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom,int left,int right,int borderType,const Scalar& value=Scalar()):
- 1:输入图像
- 2:运算结果
- 3、4、5、6:表示在原图像上的四个方向扩充多少像素
- 7:常见取值BORDERCONSTANT
- 8:默认值0
-
5.5.5、计算二维矢量的幅值:magnitude(InputArray x, InputArray y, OutputArray magnitude):
- 1:矢量的实部,X坐标值
- 2:虚部
- 3:输出的幅值,与一个有着相同的尺寸和类型
-
5.5.6、计算自然对数:log(InputArray src, OutputArray dst)
- 1:输入图像
- 2:得到的对数值
-
5.5.7、矩阵归一化:normalize(InputArray src,OutputArray dst,double alpha=1,double beta=0, int norm_type=NORM_L2,int dtype==-1,InputArray mask=noArray()):
- 1:输入图像
- 2:运算结果
- 3:归一化后的最大值默认1
- 4:归一化后的最小值,默认0
- 5:归一化类型,NORM_INF
- 6:默认值-1,表示与src有同样的类型,否则有同样的通道数,此时图像深度为CVMATDEPTH
- 7:可选的操作掩膜,默认值noArray()
-
5.5.8:程序
-
-
5.6、输入输出XML和YAML文件
-
5.6.1、XML和YAML文件用于存储和还原各式各样的数据结构。当然,它们还可以存储和载入任意复杂的数据结构 其中就包括了 OpenCV 关周边的数据结构,以及各种原始数据类型,如整数和浮点数字和文本字符串。
-
5.6.2、FileStorage类操作文件的使用引导
- 使用如下过程来写入和读取数据到XML或YAML文件中
- 实例化一个FileStorage类对象,用默认带参数的构造函数完成初始化,或FileStorage::open()成员函数辅助初始化
- 使用<<进行文件写入操作,>>进行读取操作,
- 使用FileStorage::release()函数析构FileStorage类对象,同时关闭文件
- 1、准备文件操作
- C : FileStorage : : FileStorage ()
- C : FileStorage : : FileStorage(const string& source , int flags, const string& encoding=string())C :
- FileStorage fs( " abc . xml " , FileStorage : WRITE ;
- 2、准备文件读操作
- FileStorage fs( " abc . xml " , FileStorage ::READ ;
- 2、进行文件读写操作
- 文本和数字的输入和输出
fs<< " 文本"<< 100
- 读取文件:
int itNr; fs[ " iterationNr " ] >> itNr; itNr = (int ) fs[ " iterationNr" ] ;
- opencv数据结构的输入与输出
- 初始化:
Mat R = Mat_<uchar>::eye (3,3)
; 向Mat中写入数据:fs<<"R" <<R
;从Mat中读取数据:fs["R"]>>R
- 初始化:
- 文本和数字的输入和输出
- 3、vector(arrays)和maps的输入和输出
- 对于vector的输入和输出,在第一个元素前加"[",在最后一个元素加“]”:开始读入string文本序列:
fs<<"strings"<<"[";
;fs<<"imagel.jpg"<<"Awesomeness"<<"baboon.jpg"
; 关闭序列:fs<<"]"
; - 对于map结构的操作,使用的符号是{}:开始读入mapping文本:
fs<<"mapping"<<"{";
;fs<<"one"<<,fs<<"two"<<2<<"}"
; - 读取这些结构时,会用到FileNode和FileNodeIterator结构,FileStorage 类的" 飞" "操作符会返回 FileNode 数据类型 对于一连串的 node可以使用 FileNodeIterator 结构,例如:读取字符串序列以得到节点:
FileNode n = fs["strings"]
;if(n.type()!= FileNode::SEQ){cerr<<"发生错误!字符串不是一个序列!"<<endl;return 1;}
;FileNodeIteraror it = n.begin(),it_end = n.end();
;for(; it != it_end; ++it)
;cout<<(string)*it << endl;
- 对于vector的输入和输出,在第一个元素前加"[",在最后一个元素加“]”:开始读入string文本序列:
- 4、文件关闭:fs.release()
- 使用如下过程来写入和读取数据到XML或YAML文件中
-
5.6.3、XML和YAML文件的写入
- 运行此程序会在工程目录下生成一个"test.yaml"文件,后缀也可以改成xml、yml、txt、doc
-
5.6.4、XML和YAML文件的读取
-
-
5.7、本章小结