OpenCV 函数笔记
一、图像处理基本操作
1.Mat类函数
Mat name(); 无参数构造方法;
Mat name(int rows,int cols,int type); 创建行数为rows,列数为cols,类型为type的图像;
Mat name(Size size,int type); 创建大小为size,类型为type的图像;
Mat name(int rows,int cols, int type,const Scalar&s); 创建行数为rows,列数为cols,类型为type,并赋予初值Scalar或s的图像;
Mat name(Size size,int type,const Scalar&s); 创建大小为size,类型为type,并赋予初值Scalar或s的图像;
Mat name(const Mat&m); 将m赋值给新创建的对象,此处不会对图像数据进行复制,m和新对象公用图像数据。
Size(rows,cols);创建行数为rows,列数为cols的尺寸。
Scalar(a,b,c,...);给Mat赋初值时使用,使第一个通道全为a,第二个通道全为b,以此类推。
Point(x,y);创造一个点的数据类型,使用时可以用Point.x和Point.y来单独输出坐标。
name.rows 返回Mat类的行数;
name.cols 返回Mat类的列数;
name.rowRange(a,b)返回由Mat类的第a,b行组成的矩阵;
name.colRange(a,b)返回由Mat 类的第a,b列组成的矩阵;
name.copyTo(name2)将name复制到name2中;
name.convertTo(name,type) 将name转换为type类型;
name.zeros(rows,cols,type) 返回函数为rows,列数为cols,类型为type的零矩阵;
具体用法: cv::Mat Image3 = cv::Mat::zeros(Image2.rows, Image2.cols, CV_8UC1);
name.ones(rows,cols,type) 同上,只是返回的是1矩阵;
name.channels()返回Mat类的通道数;
name.empty() 如果数组数据为空,则返回true;
name.at 返回对指定数组元素的引用;
具体用法:Image.at<type>(x,y)=a; 将Image中(x,y)坐标的元素赋值为a,type可选uchar,float,short等;
像素访问(img.at、img.ptr)
当我们进行图像处理时,可能有操作是要查访所有像素,比如说我们想要改变一张图像的灰阶值,让所有的像素值加20,这时我们就需扫过图像所有的像素,这边介绍OpenCV的at()和ptr()函式以及迭代器,来查访Mat所有像素。
at()可用来读取和修改某个像素值,通常用来对随机位置的像素进行读写,就效率考察,并不适合用在循序查访图像所有像素,以下用at()来读取img的所有像素,并让所有像素值加20:
int widthLimit = img.channels() * img.cols;
for(int height=0; height<img.rows; height ){
for(int width=0; width<widthLimit; width ){
img.at<uchar>(height, width) = 20;
}
}
ptr()函式返回指标,指向图像指定列的首像素,使用时须输入像素位深度和第几列,对于一个深度8位的图,我们可用img.ptr(j)指到第j列的第一个像素,接着逐列查访,最后可查访图像所有像素,这种方法运行速度较at()快,在分辨率大或是重视效率的地方,是比较好的方法,以下用ptr()来读取img的所有像素,并让所有像素值加20:
int widthLimit = img.channels() * img.cols;
for(int height=0; height<img.rows; height ){
uchar *data = img.ptr<uchar>(height);
for(int width=0; width<img.widthLimit ; width ){
data[width] = 20;
}
}
2.图像读取显示保存
Mat imread(const string&filename, int flags=1)
读取图像文件。filename表示读取文件的地址文件名;flags表示读取图像的颜色类型,默认为1,函数返回3通道图像。
参数flag=CV_LOAD_IMAGE_ANYDEPTH时,表示返回16bit或32bit图像(当输入为相同深度时),否则返回8bit图像;
设置为CV_LOAD_IMAGE_COLOR时,函数返回单色图像;
设置为CV_LOAD_IMAGE_GRAYSCALE时,函数返回为通道图像;
另外flags可设置为0,该函数返回单通道图像;
flags小于0则不进行通道转换;
flags大于0,函数将强制返回3通道图像。
bool imwrite(const string&filename, InputArray img, const vector<int>¶ms=vector<int>() )
保存文件图像。参数filename表示写入文件的格式及文件拓展名;img表示待写入图像源;params表示文件格式的一些细节信息,参数里面的数值跟文件格式有关,其中JPEG表示图像的质量,取值范围从0~100;PNG表示压缩级别,取值范围为0~9;PPM、PGM或PBM表示文件是以二进制还是纯文本方式存储,取值为0或1。
blur(srcImage,blurDstImage,cv::Size(a,b),cv::Point(c,d));
将图像srcImage进行均值滤波处理,处理结果存入blurDstImage中。
cv::cvtColor(srcImage,srcGray,CV_RGB2GRAY);
将图像srcImage转换成灰度图像,处理结果存入srcGray中。
3.图像几何变换
void remap(InputArraysrc, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int bordeMode=BORDER_CONSTANT, const Scalar&borderValue=Scalar())
图像重映射操作。重映射是指把一个图像中一个位置的像素通过映射关系转换到另一图像的指定位置。
src是输入图像;
dst是输出图像;
map1表示(x,y)点的坐标或x坐标,可以是CV_16SC2,CV_32FC1或CV_32FC2类型;
map2表示y坐标,可以是CV_16UC1,CV_32FC1类型,如果map1表示(x,y),map2则可以选择不用;
interpolation表示插值方法;
BORDERMode表示边界插值类型;
borderValue表示插值数值。
static_cast < type-id > ( expression ) 将expression的结果强制转换成type-id的类型,但没有运行时类型检测来保证转换的安全性。
Point_<int> a; 定义a是以整数为坐标(x,y)的数据类型,即a=(int x,int y)。
transpose(srcImage,resultImage); 逆时针旋转90°;
flip(srcImage,resultImage,k); k=1时是水平翻转;k=0时是垂直翻转;k=-1时垂直和水平翻转;
getRotationMatrix2D(Point2f center, double angle, double scale); 根据中心点及旋转角度计算仿射变换的矩阵函数,输入的三个参数分别为中心点坐标(x,y),旋转角度angle以及放缩比例scale,输出的即2x3的仿射变换矩阵。
getAffineTransform(srcPoint,resPoint); 根据三点法计算仿射变换的矩阵函数。srcPoint为源图像的三个不共线的点;resPoint为仿射后的三个不共线的点;输出的即2x3的仿射变换矩阵。
warpAffine(srcImage,resultImage,warpMat,resultImage.size()); 仿射变换函数。根据仿射变换矩阵warpMat,对srcImage进行仿射变换,结果存入resultImage中。
二、图像灰度变换技术
2.1阈值化处理
阈值化操作就是利用图像像素点分布规律,设定阈值进行像素点分隔,进而得到图像的二值图像。
2.1.1 OTSU阈值化
OTSU阈值化函数具体程序实现见P76代码3-1的样例;
2.1.2 固定阈值化
Opencv中提供了阈值化函数threshold,具体内容如下:
void threshold(InputArraysrc,OutputArray dst,double thresh,doublemaxval,int type)
参数src表示源图像数组(单通道,8位或32位浮点数据);
参数dst表示输出图像组(与输入图像同样尺寸和类型);
thresh表示阈值设置;
maxval表示预设最大值,在函数类型设置参数type使用THRESH_BINARY或THRESH_BINARY_INV类型时有用;
type表示阈值化处理的类型设置,type=0,1,2,3,4时对应的5种类型具体介绍见下文:
(0)THRESH_BINARY二进制阈值化
(1)THRESH_BINARY_INV反二进制阈值化
(2)THRESH_TRUNC截断阈值化
(3)THRESH_TOZERO阈值化为0
(4)THRESH_TOZERO_INV反阈值化为0
各种处理效果见下图:
2.1.3自适应阈值化
OpenCV中提供了自适应阈值化函数adaptiveThreshold,该函数有两种自适应阈值化类型参数可供选择,用来对当前像素点与领域像素块进行阈值计算,具体内容如下:
void adaptiveThreshold (InputArraysrc,OutputArray dst,double maxValue,int adptiveMethod, int thresholdType, int blockSize, double C)
参数src表示源图像数组(单通道,8位或32位浮点数据);
参数dst表示输出图像组(与输入图像同样尺寸和类型);
maxval表示预设满足条件的最大值;
参数adaptiveMethod=0,1分别表示自适应阈值算法选择ADAPTIVE_THRESH_MEAN_C或ADAPTIVE_THRESH_GAUSSIAN_C;
参数thresholdType=0,1分别表示阈值类型THRESH_BINARY或THRESH_BINARY_INV;
参数blockSize表示邻域块大小,用来计算区域阈值,一般选择为3,5,7,...;
参数C表示常数,是一个从均值或加权均值提取的常数,可以是负数;
根据参数不同对应四种处理效果如下:
2.1.4 双阈值化
对于图像有明显的双分界特征,我们考虑用双阈值化进行二值化处理。处理原则如下:
利用threshold函数进行实现,具体实现方法见P83页代码3-4。
bitwise_and,bitwise_or, bitwise_not , bitwise_xor (src1,src2,src) 将图片src1与src2的各个位置的元素进行位运算,分别为与、或、非、异或,结果存入src中。
2.1.5 半阈值化
对于图像中有明显的目标与背景差异特征,如手写体字符分割与识别,我们可以考虑用半阈值法进行阈值化操作。处理原则如下:
利用threshold函数进行实现,具体实现方法见P84页代码3-5。
2.2 直方图处理
2.2.1 灰度直方图
OpenCV提供了简单的计算数组集(通常是图像或分割后的通道)的直方图函数如下:
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false)
参数images表示输入图像源指针,图像源必须是同样的深度信息,可以有任意通道数;
参数nimages表示待计算图像源中图像的个数,用于单幅图像计算直方图时常为1;
参数channels表示需要统计图像的通道维数数组索引,第一个数组的通道由0到array[0].channels()-1,以此类推;
参数mask表示可选掩码参数,如果矩阵不为空,该掩码参数必须是8-bit且需要和图像源同样尺寸,掩码的非零值标记需要在直方图中统计数组元素,默认设置为空图像;
参数hist输出计算得到的直方图,通常是一个稠密或稀疏的多维数组;
参数dims输出直方图的维数,必须为正(目前最大为32),灰度图像为1维,彩色图像为3维;
参数histSize表示直方图横坐标的区间数;
参数ranges表示用于指出直方图每一维的每个bin的上下界范围数组的数组,对于均匀直方图,参数ranges是一个包含两个元素的数组;
参数uniform是表示直方图是否均匀;
参数accumulate累计标志,用于设置是否清除开始分配时的直方图累计标志;
2.2.5 灰度直方图均衡
通常我们很难观察一幅非常亮或暗的图像的细节信息,因此对于差异较大的图像,我们可以尝试改变其图像灰度分布来使图像灰度阶分布尽量均匀,进而增强图像细节信息。
void equalizeHist(InputArray srcGray,OutputArray heqResult);
将输入图像源srcGray进行灰度直方图均衡后,输出至heqResult中。
2.2.6 彩色直方图均衡
Std::vector<cv::Mat>name 相当于cv::Mat name[]
vector(向量): C 中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的.
voidsplit(const Mat& src,Mat* mvBegin)
或void split(InputArray src, vector<Mat>& mv);
Split函数的功能是使图像通道分离,通常与vector一起使用,但建议使用直接定义数组的方式,因为用vector容易报错,例子如下:
std::vector<Mat> channels;
Mat aChannels[3];
//src为要分离的Mat对象
split(src, aChannels); //利用数组分离
split(src, channels); //利用vector对象分离
imshow("B",channels[0]);
imshow("G",channels[1]);
imshow("R",channels[2]);
void merge(const vector<Mat>& mv, OutputArray dst );
merge 与split函数相反。可以将多个单通道图像合成一幅多通道图像。
五、边缘检测技术
5.1 边缘检测基础
5.1.1 图像差分运算
void addWeighted(InputArraysrc1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);
图像叠加函数
参数src1图像1;
参数alpha图像1所占的权重;
参数src2图像2;
参数beta图像2所占的权重;
参数gamma表示元素在图像1,2叠加后再另加上的标量,不需要时为0;
参数dst叠加后输出的图像;
参数dtype,希望输出后的图像深度,若两幅图像深度相同,可以设为-1表示使用图1的深度。
5.2基本边缘检测算子----Sobel
CV_Assert(expression)
expression参数含义:检查的对象;
若expression=0,则返回报错信息;
void filter2D( InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT );
利用内核实现对图像的卷积运算的函数。
参数src,dst分别表示输入图像和输出图像;
参数ddepth目标图像深度,如果没写将生成与原图像深度相同的图像,当ddepth=-1时,表示目标图像与源图像深度保持一致;
参数kernel是卷积核(或者是相关核),一个单通道浮点型矩阵;
参数anchor是内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点;
参数delta是在储存目标图像前可选的添加到像素的值,默认值为0;
参数borderType是像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。
OpenCV 中提供了如下的一些函数,用来进行图像的加减乘除。
void add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray(), int dtype=-1);
void subtract(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray(), int dtype=-1);
void multiply(InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1);
void divide(InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1);
void divide(double scale, InputArray src2, OutputArray dst, int dtype=-1);
void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);
这些函数都要求相加的两幅图像具有相同的尺寸,并且像素类型是相同的。
Scalar mean(InputArraysrc, InputArray mask = noArray());
对图像src进行求均值的计算,注意得到的结果是Scalar类型,需要使用时要用mean(src).val[0]来访问;
void convertScaleAbs(InputArraysrc, OutputArray dst, double alpha=1, double beta=0)
将图片转化成为8位图形。
OpenCV提供了Sobel函数来计算图像边缘,介绍如下
void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale= 1, double delta = 0, int borderType = BORDER_DEFAULT );
void Scharr( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale= 1, double delta = 0, int borderType = BORDER_DEFAULT );
参数ddepth是输出图像的深度;
参数dx为x方向的导数运算参数;
参数dy为y方向导数运算参数;
参数ksize为Sobel内核的大小,设置为奇数,默认参数为3,此时内核因子计算可能会产生一定误差,OpenCV提供了更精确内核因子及Scharr函数,此时该值为0或1;
参数scale为可选的缩放导数的比例常数;
参数delta为可选的增量常数,被叠加到导数中;
参数borderType用于判断图像边界的模式。
5.3基本边缘检测算子——Laplace
OpenCV提供拉普拉斯边缘检测函数,
void Laplacian( InputArray src, OutputArray dst, int ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
参数ddepth是输出图像的深度;
参数ksize用于计算二阶滤波器的参数,只能取正奇数值;
参数scale是处理后图像的像素值的缩放倍数;
参数delta是处理后图像的像素值另外需要加上的数值,通常为0;
5.4基本边缘检测算子——Roberts
5.5基本边缘检测算子——Prewitt
5.6改进边缘检测算子——Canny
void Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false );
参数image为输入图像,单通道8bit;
参数edges为输出图像,类型尺寸与输入图像相同;
参数threshold1为第一滞后过程阈值;threshold2为第二滞后过程阈值;
参数apertureSize为索贝尔操作的尺寸因子;
参数L2gradient为标志位,表示是否使用L2范数来计算图像梯度大小。
5.7改进边缘检测算子——Marr-Hildreth
5.8几何检测
5.8.1基于霍夫变换的线检测技术
void HoughLinesP( InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength = 0, double maxLineGap= 0 );
参数image为输入的8位单通道二值化图像;
参数lines为输出线向量,每个线向量由4个元素(x1,y1,x2,y2)组成,其中(x1,y1)和(x2,y2)为线段的端点坐标;
参数rho为累计像素的距离分辨率;
参数theta为累计弧度的角度分辨率;
参数threshold表示要检测一条直线所需最少的曲线交点,通俗来说就是算法检测直线的精度设置,数值越高,检测到的直线越少;
参数minLineLength为最小的线长度;
参数maxLineLength为最大的线长度,用于线段连接;
void HoughLines( InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn = 0, double stn = 0, double min_theta = 0, double max_theta = CV_PI );
参数image为输入的8位单通道二值化图像;
参数lines为输出线向量,每个线向量由2个元素(
)组成,其中
为距离原点的距离,
为线旋转角;
参数rho为累计像素的距离分辨率;
参数theta为累计弧度的角度分辨率;
参数threshold表示要检测一条直线所需最少的曲线交点,通俗来说就是算法检测直线的精度设置,数值越高,检测到的直线越少;
参数srn为多尺度霍夫变换参数,是一个距离分辨率
因子;
参数stn为多尺度霍夫变换参数,是一个距离分辨率
因子;
void line(InputOutputArrayimg, Point pt1, Point pt2, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift= 0);
用于在图img中连接pt1和pt2两点画直线的函数,参数color是线的颜色,thickness是线宽,lineType是线型,shift是坐标点小数点位数;
5.8.2 LSD线检测技术
Ptr<LineSegmentDetector>name=createLineSegmentDetector(LSD_REFINE_STD)
创建LSD检测类,用于下述线检测;
name->detect(src,vecLines) 在src图像中进行线检测,将结果存入vecLines中
name->drawSegment(dst,vecLines) 在dst图像中绘制线分割线
5.8.3霍夫圆检测
void HoughCircles( InputArray image, OutputArray circles, int method, double dp, double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius= 0 );
进行霍夫圆检测的函数,image为输入图像8位单通道灰度图像;
参数circles为检测的圆信息,(circles[0],circles[1])为圆心,circles[2]为半径;
参数method为使用霍夫变换圆检测的算法,参数是CV_HOUGH_GRADIENT;
参数dp为第一阶段所使用的霍夫空间的分辨率,dp=1时表示霍夫空间与输入图像空间的大小一致,dp=2时霍夫空间是输入图像空间的一半,以此类推;
参数minDist为圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是同一个圆心;
参数param1为边缘检测时使用Canny算子的高阈值
参数param2为步骤1.5和步骤2.5中所共有的阈值
参数minRadius和maxRadius为所检测到的圆半径的最小值和最大值
void circle(InputOutputArrayimg, Point center, int radius, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift= 0);
在图像img中绘制圆心为center,半径为radius的圆的函数;
参数color为圆的颜色,采用Scalar的RGB形式;
参数thickness是圆的粗细;
参数lineType是圆的线型;
参数shift是小数点位数;
5.9形状检测
5.9.1轮廓检测
OpenCV提供了findContours()函数用于对物体轮廓进行检测:
void findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArrayhierarchy, int mode, int method, Point offset = Point());
参数img为输入图像,8位单通道灰度图像;
参数contours为检测到的轮廓,每个轮廓都在向量中;
参数hierarchy为包含图像拓扑结构的信息;
参数mode为可选获取轮廓的方法,常用参数有外轮廓CV_RETR_EXTERNAL,CV_RETR_LIST为检测所有轮廓的不包含继承关系,CV_RETR_TREE为检测所有轮廓的包含继承关系,CV_RETR_CCOMP为检测所有轮廓,但是仅仅建立两层包含关系;
参数method为轮廓近似的方法,参数设置是CV_CHAIN_APPROX_NONE表示把轮廓上所有的点存储,CV_CHAIN_APPROX_SIMPLE表示只储存水平、垂直及对角直线的起始点;
参数offset为可选的偏移量。
注意:findContours()运行的时候,这个图像会被直接涂改,因此如果是将来还有用的图像,应该复制之后再传给findContours()。
void drawContours( InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness = 1, int lineType= LINE_8, InputArray hierarchy = noArray(), int maxLevel = INT_MAX, Point offset = Point() );
参数image,//要绘制轮廓的图像;
参数 contours,//所有输入的轮廓,每个轮廓被保存成一个point向量;
参数contourIdx,//指定要绘制轮廓的编号,如果是负数,则绘制所有的轮廓;
参数color,//绘制轮廓所用的颜色
参数thickness = 1, //绘制轮廓的线的粗细,如果是负数,则轮廓内部被填充
参数lineType = 8, /绘制轮廓的线的连通性
参数hierarchy = noArray(),//关于层级的可选参数,只有绘制部分轮廓时才会用到;
参数 maxLevel = INT_MAX,//绘制轮廓的最高级别,这个参数只有hierarchy有效的时候才有效
//maxLevel=0,绘制与输入轮廓属于同一等级的所有轮廓即输入轮廓和与其相邻的轮廓
//maxLevel=1,绘制与输入轮廓同一等级的所有轮廓与其子节点。
//maxLevel=2,绘制与输入轮廓同一等级的所有轮廓与其子节点以及子节点的子节点
参数Point offset = Point()
5.9.2凸包检测
凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。
void convexHull( InputArray points, OutputArray hull, bool clockwise = false, bool returnPoints= true );
实现一个点集的凸包检测;
参数points表示输入2维点集,可存储在向量或矩阵Mat中;
参数hull为输出凸包,这是一个整数索引的载体或点的矢量;
参数clockwise为方向标志位;
参数returnPoints为操作标准位。
void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects );
完成凸包缺陷轮廓操作;
参数contour表示输入参数检测到的轮廓,可以通过调用findContours函数得到;
参数convexhull表示输入参数检测到的凸包,可以调用凸包convexHull函数得到,该函数可以得到vector<vector<Point>>和vector<vector<int>>两种类型结果,凸包检测函数应该为后者的类型,否则无法通过assert检查;
参数convexityDefects为输出参数,检测到的最终结果应为vector<vector<Vec4i>>类型,储存了起始点、结束点、距离以及最远点到凸包的距离四个信息。
5.10角点检测
void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );
高斯滤波函数;
src和dst分别是输入图像和输出图像。ksize为高斯滤波器模板大小,sigmaX和sigmaY分别为高斯滤波在横线和竖向的滤波系数。borderType为边缘点插值类型。
void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true,int borderType = BORDER_DEFAULT );
盒滤波函数;
src和dst分别是输入图像和输出图像。
参数ddepth是滤波后的图像深度,=-1时与输入图像一致;
Ksize为盒滤波器模板大小;
参数normalize表示是否归一化的标志;
void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray());
归一化函数;
参数src 是输入图像,dst 输出图像,支持自身运算;
参数alpha是 range normalization模式的最小值
参数beta是range normalization模式的最大值,不用于norm normalization(范数归一化)模式。
参数normType归一化的类型,可以有以下的取值:
NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用。
NORM_INF:此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)
NORM_L1 :归一化数组的L1-范数(绝对值的和)
NORM_L2:归一化数组的(欧几里德)L2-范数
参数dtype是类型,dtype为负数时,输出图像的type与输入图像的type相同;否则,输出数组与输入数组只是通道数相同,而tpye=CV_MAT_DEPTH(dtype).
参数mask是操作掩膜,用于指示函数是否仅仅对指定的元素进行操作。
OpenCV提供了Shi=Tomasi角点检测的函数,如下:
void goodFeaturesToTrack( InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask = noArray(), int blockSize = 3, bool useHarrisDetector = false, double k = 0.04 );
参数image:8位或32位浮点型输入图像,单通道
参数corners:保存检测出的角点
参数maxCorners:角点数目最大值,如果实际检测的角点超过此值,则只返回maxCorners个强角点
参数qualityLevel:角点的品质因子
参数minDistance:对于初选出的角点而言,如果在其周围minDistance范围内存在其更强角点,则将此角点删除
参数mask:指定感兴趣区,如不需在整幅图上寻找角点,则用此参数指定ROI
参数blockSize:计算协方差矩阵时的窗口大小
参数useHarrisDetector:指示是否使用Harris角点检测,如不指定,则计算shi-tomasi角点
参数k:Harris角点检测需要的k值
void medianBlur( InputArray src, OutputArray dst, int ksize );
中值滤波函数;
参数ksize是平滑核因子;
6.直方图绘制
void calcHist( const Mat* images, int nimages, const int* channels, InputArraymask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform= true, bool accumulate = false );
参数image是指针,因此可以同时处理多张类型尺寸相同的图像;
参数nimages表示使用多少张图像序列中的图像进行处理;
参数channels指定哪些通道的图像会被使用,按图像序列的不同通道数依次排序;
参数mask是掩膜操作,指定图像某一区域进行直方图计算;
参数hist是输出的直方图结果矩阵,有可能是多维的;
参数dims是需要计算的直方图维数;
参数histSize计算直方图的每一维的大小,即每一维bin的个数;
参数ranges是所需计算直方图的每一维的范围,若uniform=true,则ranges包含两个数值,分别表示上下限;若uniform=false,则ranges包含histSize个数值;ranges包含的数值需要人为指定,即每一维的坐标值不一定是均匀的;
参数uniform如果为true的话,则说明所需计算的直方图的每一维按照它的范围和尺寸大小均匀取值;
参数accumulate如果为false,则表示直方图输出矩阵hist在使用该函数的时候被清0了,如果为true,则表示hist在使用calcHist()函数时没有被清0,计算的结果会累加到前一次保存的值中。
7.傅里叶变换
void copyMakeBorder(InputArraysrc, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar& value = Scalar());
扩充src的边缘,将图像变大,然后以各种外插方式自动填充图像边界
src,dst:原图与目标图像
top,bottom,left,right分别表示在原图四周扩充边缘的大小
borderType:扩充边缘的类型,就是外插的类型,OpenCV中给出以下几种方式
* BORDER_REPLICATE
* BORDER_REFLECT
* BORDER_REFLECT_101
* BORDER_WRAP
* BORDER_CONSTANT
*BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
* BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
* BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
* BORDER_WRAP: cdefgh|abcdefgh|abcdefg
* BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'
int getOptimalDFTSize(intvecsize);
获得最佳的扩展后的行列数,以便进行傅里叶计算;
参数vecsize是输入拓展前源图像的行或者列;
注意:
1.在有图片读取或储存的程序中,结尾使用std::getchar();会导致图片加载不出来,最好使用cv::waitKey(0);
2.在使用imwrite()函数的时候,要注意将debug模式改为release模式
3.使用Mat::at引用图片数组值的时候,要注意引用的坐标(x,y)不要越界,即x<srcImage.cols&&y<srcImage.rows,注意,没有等号,且通常srcImage.cols=2时,说明有2行,但是x的取值坐标只能为0,1,因为矩阵下标是从0开始的。
4.注意Mat::at<type>(i,j)中的type一定要与定义的Mat对应,且i表示行数(也就是row),j表示列数(也就是col),注意不要弄反了。且应当注意,在坐标(x,y)中,i对应的是y,j对应的是x。
5.对图像进行边缘检测的时候,要注意先将彩色图像灰度化,因为大部分算法都是以灰度图像为基础的。
6.△△△(很很很重要!!!!)把示例的代码复制进去都还是出错,说明是配置出了问题。链接器中的输入附加依赖项的*lib改成了world310d.lib,问题就解决了。之前刚安装的时候,别人误导了,其实只用添加一个依赖项,即opencv_world310d.lib即可。310d表示的意思是opencv版本为3.1,d表示debug。
一些基础知识:
1.数字图像:每一个数字图像都是一个像素点矩阵,这个矩阵包含所有像素点的强度值
2.通道:把图像分解成一个或多个颜色成分
①单通道:一个像素点只需一个数值表示,只能表示灰度,0为黑色
②三通道:RGB模式,把图像分为红绿蓝三个通道,可以表示彩色,全0表示黑色
③四通道:在RGB基础上加上alpha通道,表示透明度,alpha=0表示全透明
3.深度:深度即位数(比特数)
①位深:一个像素点所占的总位数,也叫像素深度、图像深度等
* 位深 = 通道数 × 每个通道所占位数
②256色图:n位的像素点可以表示2^n种颜色,称2^n色图,n=8时为256色图
③8位RGB与8位图:前者的位数指每个通道所占的位数,后者指整个像素点共占的位数
*8位RGB是一个24位图,也称为真彩
4.openCV提供的一些矩阵运算的函数
Function (函数名) | Use (函数用处) |
Author : Ggicci | |
add | 矩阵加法,A B的更高级形式,支持mask |
scaleAdd | 矩阵加法,一个带有缩放因子dst(I) = scale * src1(I) src2(I) |
addWeighted | 矩阵加法,两个带有缩放因子dst(I) = saturate(src1(I) * alpha src2(I) * beta gamma) |
subtract | 矩阵减法,A-B的更高级形式,支持mask |
multiply | 矩阵逐元素乘法,同Mat::mul()函数,与A*B区别,支持mask |
gemm | 一个广义的矩阵乘法操作 |
divide | 矩阵逐元素除法,与A/B区别,支持mask |
abs | 对每个元素求绝对值 |
absdiff | 两个矩阵的差的绝对值 |
exp | 求每个矩阵元素 src(I) 的自然数 e 的 src(I) 次幂 dst[I] = esrc(I) |
pow | 求每个矩阵元素 src(I) 的 p 次幂 dst[I] = src(I)p |
log | 求每个矩阵元素的自然数底 dst[I] = log|src(I)| (if src != 0) |
sqrt | 求每个矩阵元素的平方根 |
min, max | 求每个元素的最小值或最大值返回这个矩阵 dst(I) = min(src1(I), src2(I)), max同 |
minMaxLoc | 定位矩阵中最小值、最大值的位置 |
compare | 返回逐个元素比较结果的矩阵 |
bitwise_and, bitwise_not, bitwise_or, bitwise_xor | 每个元素进行位运算,分别是和、非、或、异或 |
cvarrToMat | 旧版数据CvMat,IplImage,CvMatND转换到新版数据Mat |
extractImageCOI | 从旧版数据中提取指定的通道矩阵给新版数据Mat |
randu | 以Uniform分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::UNIFORM) |
randn | 以Normal分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::NORMAL) |
randShuffle | 随机打乱一个一维向量的元素顺序 |
theRNG() | 返回一个默认构造的RNG类的对象 theRNG()::fill(...) |
reduce | 矩阵缩成向量 |
repeat | 矩阵拷贝的时候指定按x/y方向重复 |
split | 多通道矩阵分解成多个单通道矩阵 |
merge | 多个单通道矩阵合成一个多通道矩阵 |
mixChannels | 矩阵间通道拷贝,如Rgba[]到Rgb[]和Alpha[] |
sort, sortIdx | 为矩阵的每行或每列元素排序 |
setIdentity | 设置单元矩阵 |
completeSymm | 矩阵上下三角拷贝 |
inRange | 检查元素的取值范围是否在另两个矩阵的元素取值之间,返回验证矩阵 |
checkRange | 检查矩阵的每个元素的取值是否在最小值与最大值之间,返回验证结果bool |
sum | 求矩阵的元素和 |
mean | 求均值 |
meanStdDev | 均值和标准差 |
countNonZero | 统计非零值个数 |
cartToPolar, polarToCart | 笛卡尔坐标与极坐标之间的转换 |
flip | 矩阵翻转 |
transpose | 矩阵转置,比较 Mat::t() AT |
trace | 矩阵的迹 |
determinant | 行列式 |A|, det(A) |
eigen | 矩阵的特征值和特征向量 |
invert | 矩阵的逆或者伪逆,比较 Mat::inv() |
magnitude | 向量长度计算 dst(I) = sqrt(x(I)2 y(I)2) |
Mahalanobis | Mahalanobis距离计算 |
phase | 相位计算,即两个向量之间的夹角 |
norm | 求范数,1-范数、2-范数、无穷范数 |
normalize | 标准化 |
mulTransposed | 矩阵和它自己的转置相乘 AT * A, dst = scale(src - delta)T(src - delta) |
convertScaleAbs | 先缩放元素再取绝对值,最后转换格式为8bit型 |
calcCovarMatrix | 计算协方差阵 |
solve | 求解1个或多个线性系统或者求解最小平方问题(least-squares problem) |
solveCubic | 求解三次方程的根 |
solvePoly | 求解多项式的实根和重根 |
dct, idct | 正、逆离散余弦变换,idct同dct(src, dst, flags | DCT_INVERSE) |
dft, idft | 正、逆离散傅立叶变换, idft同dft(src, dst, flags | DTF_INVERSE) |
LUT | 查表变换 |
getOptimalDFTSize | 返回一个优化过的DFT大小 |
mulSpecturms | 两个傅立叶频谱间逐元素的乘法 |
5.C语言的一些知识
#if 0
A
#else
B
#endif
改代码的意思是#if 0 之后的A永远不会执行,肯定会执行B。用于调试,将0改为1就可以尝试A而不编译B
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved