OpenCV学习笔记2.docx
《OpenCV学习笔记2.docx》由会员分享,可在线阅读,更多相关《OpenCV学习笔记2.docx(8页珍藏版)》请在冰豆网上搜索。
OpenCV学习笔记2
第二章数据结构
OpenCV核心库的数据结构
一、基本数据结构
CvPoint、CvPoint2D32f、CvPoint3D32f、
CvSize、CvSize2D32f、CvSize3D32f、CvRect
CvScalar(N元组)
CvMat、CvMatND、CvSpareseMat、CvTermCriteria、CvArr、Iplimage
例题4-1:
基本数据类型使用
说明:
cvFlip:
垂直,水平或即垂直又水平翻转二维数组
voidcvFlip(constCvArr*src,CvArr*dst=NULL,intflip_mode=0);
flip_mode:
指定怎样去翻转数组。
flip_mode=0沿X-轴翻转,
flip_mode>0(如1)沿Y-轴翻转,
flip_mode<0(如-1)沿X-轴和Y-轴翻转.见下面的公式
函数cvFlip以三种方式之一翻转数组(行和列下标是以0为基点的):
dst(i,j)=src(rows(src)-i-1,j)ifflip_mode=0
dst(i,j)=src(i,cols(src1)-j-1)ifflip_mode>0
dst(i,j)=src(rows(src)-i-1,cols(src)-j-1)ifflip_mode<0
二、数组有关的结构
1、数组定义
IplImage和cvMat结构的基本使用方法
IplImage:
图像结构
typedefstruct_IplImage
{
intnSize;/*IplImage大小*/
intID;/*版本(=0)*/
intnChannels;/*大多数OPENCV函数支持1,2,3或4个通道*/
intalphaChannel;/*被OpenCV忽略*/
intdepth;/*像素的位深度:
IPL_DEPTH_8U,IPL_DEPTH_8S,
IPL_DEPTH_16U,
IPL_DEPTH_16S,IPL_DEPTH_32S,
IPL_DEPTH_32FandIPL_DEPTH_64F可支持*/charcolorModel[4];/*被OpenCV忽略*/
charchannelSeq[4];/*同上*/
intdataOrder;/*0-交叉存取颜色通道,1-分开的颜色通道.
cvCreateImage只能创建交叉存取图像*/intorigin;/*0-顶—左结构,
1-底—左结构(Windowsbitmaps风格)*/
intalign;/*图像行排列(4or8).OpenCV忽略它,使用widthStep代
替*/
intwidth;/*图像宽像素数*/
intheight;/*图像高像素数*/
struct_IplROI*roi;/*图像感兴趣区域.当该值非空只对该区域进行处理*/
struct_Iplimage*maskROI;/*在OpenCV中必须置NULL*/
void*ImageId;/*同上*/
struct_IplTileInfo*tileInfo;/*同上*/
intimageSize;/*图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/
char*imageData;/*指向排列的图像数据*/
intwidthStep;/*排列的图像行大小,以字节为单位*/
intBorderMode[4];/*边际结束模式,被OpenCV忽略*/
intBorderconst[4];/*同上*/
char*imageDataOrigin;/*指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的*/
}
IplImage;
IplImage结构来自于IntelImageProcessingLibrary(是其本身所具有的)。
OpenCV只支持其中的一个子集:
例题4-2:
显示图像信息。
图像处理函数:
IplImage*cvCreateImage(CvSizesize,intdepth,intchannels);
VoidcvReleaseImage(IplImage**image);
IplImage*cvCloneImage(constIplImage*image);
VoidcvConvertImage(constCvArr*src,CvArr*dst,intflags=0);
Flages:
0:
没变化,1:
垂直翻转,2交换红蓝信道)
VoidcvSetImageCOI(IplImage*image,intcoi);根据给定值coi设置感兴趣信道
IntcvGetImageCOI(constIplImage*image);返回感兴趣信道号
VoidcvSetImageROI(IplImage*image,CvRectrect);基于给定的矩形设置ROI(RegionOfInterest)感兴趣区域
VoidcvResetImageROI(IplImage*image);释放图像的ROI
CvRectcvGetImageROI(constIplImage*image);返回图像ROI坐标
IplImage*cvGetImage(constCvArr*arr,IplImage*image_header);从不确定数组返回图像头。
输入数组可以是CvMat*或IplImage*。
例4-3:
IplImage相关函数及ROI设定与获取
2、CvMat矩阵
(1)CvMat相关函数
CvMat*cvCreateMat(introws,intcols,inttype);创建矩阵(行数、列数、元素类型)元素类型type:
通常以CV_<比特数>(S|U|F)C<通道数>的形式描述,例如:
CV_8UC1:
表示一个8bit无符号单信道矩阵;
CV_8SC1:
表示一个8bit有符号单信道矩阵;
CV_32SC:
表示一个32bit有符号双信道矩阵;
CvMat*cvCreateMatHeader(introws,intcols,inttype);创建新的矩阵头,但并没有分配数据
CvMat*cvInitMatHeader(CvMat*mat,introws,intcols,inttype,void*data=NULL,intstep=CV_AUTOSTEP);初始化矩阵头,data:
指向分配给矩阵头的数据指针。
CvMatcvMat(introws,intcols,inttype,void*data=NULL);用于替代函数cvInitMatHeader。
CvMat*cvCloneMat(constCvMat*mat);矩阵复制
VoidcvReleaseMat(CvMat**mat);删除矩阵
voidcvGEMM(constCvArr*src1,constCvArr*src2,doublealpha,
constCvArr*src3,doublebeta,CvArr*dst,inttABC=0);
#definecvMatMulAdd(src1,src2,src3,dst)cvGEMM(src1,src2,1,src3,1,dst,0)
#definecvMatMul(src1,src2,dst)cvMatMulAdd(src1,src2,0,dst)
src1
第一输入数组
src2
第二输入数组
src3
第三输入数组(偏移量),如果没有偏移量,可以为空(NULL)。
dst
输出数组
tABC
T操作标志,可以是0或者下面列举的值的组合:
CV_GEMM_A_T-转置src1
CV_GEMM_B_T-转置src2
CV_GEMM_C_T-转置src3
例如,CV_GEMM_A_T+CV_GEMM_C_T对应
alpha*src1T*src2+beta*src3T
函数cvGEMM执行通用矩阵乘法:
dst=alpha*op(src1)*op(src2)+beta*op(src3),这里op(X)是X或者XT
所有的矩阵应该有相同的数据类型和协调的矩阵大小。
支持实数浮点矩阵或者复数浮点矩阵例4:
cvMat处理函数(创建矩阵、矩阵相乘)
(2)复制和添加相关函数
voidcvCopy(constCvArr*src,CvArr*dst,constCvArr*mask=NULL);
如果输入输出数组中的一个是Iplimage类型的话,其ROI和COI将被使用。
voidcvSet(CvArr*arr,CvScalarvalue,constCvArr*mask=NULL);
如果数组arr是IplImage类型,那么就会使用ROI,但COI不能设置。
voidcvSetZero(CvArr*arr);
#definecvZerocvSetZero清空数组
voidcvSetIdentity(CvArr*mat,CvScalarvalue=cvRealScalar
(1));初始化带尺度的单位矩阵
voidcvRange(CvArr*mat,doublestart,doubleend);用指定范围的数来填充矩阵
例题4-5矩阵元素添加
(3)数组变换
CvMat*cvReshape(constCvArr*arr,CvMat*header,intnew_cn,intnew_rows=0);
不拷贝数据修改矩阵/图像形状(通道数、行数)
voidcvRepeat(constCvArr*src,CvArr*dst);用原数组管道式添充输出数组dst(i,j)=src(imodrows(src),jmodcols(src))
voidcvFlip(constCvArr*src,CvArr*dst=NULL,intflip_mode=0);
垂直,水平或即垂直又水平翻转二维数组
voidcvSplit(constCvArr*src,CvArr*dst0,CvArr*dst1,CvArr*dst2,CvArr*dst3);
分割多通道数组成几个单通道数组或者从数组中提取一个通道
voidcvMerge(constCvArr*src0,constCvArr*src1,constCvArr*src2,constCvArr*src3,CvArr*dst);从几个单通道数组组合成多通道数组或插入一个单通道数组
voidcvRandShuffle(CvArr*mat,CvRNG*rng,doubleiter_factor=1.);随机交换数组的元素
例题4-6数组变换
(4)获取数组元素和数组子集
CvMat*cvGetSubRect(constCvArr*arr,CvMat*submat,CvRectrect);
返回输入的图像或矩阵的矩形数组子集的矩阵头
CvMat*cvGetRow(constCvArr*arr,CvMat*submat,introw);
CvMat*cvGetRows(constCvArr*arr,CvMat*submat,intstart_row,intend_row,intdelta_row=1);
返回数组的一行或在一定跨度内的行
CvMat*cvGetCol(constCvArr*arr,CvMat*submat,intcol);
CvMat*cvGetCols(constCvArr*arr,CvMat*submat,intstart_col,intend_col);
返回数组的一列或一定跨度内的列
CvMat*cvGetDiag(constCvArr*arr,CvMat*submat,intdiag=0);
返回一个数组对角线(diag=0:
主对角线,diag=-1主对角线上面的对角线,diag=1主对角线下面的对角线,以此类推)
CvSizecvGetSize(constCvArr*arr);
返回图像或矩阵的行数和列数,如果是图像就返回ROI的大小
intcvGetElemType(constCvArr*arr);返回数组元素类型
intcvGetDims(constCvArr*arr,int*sizes=NULL);返回数组维数大小
intcvGetDimSize(constCvArr*arr,intindex);返回特殊维的大小
voidcvClearND(CvArr*arr,int*idx);清除指定数组元素
宏CV_MAT_ELEM(mat,elemtype,row,col)获取cvMat元素
宏CV_image_ELEM(Image,elemtype,row,col)获取IplImage元素灰度值。
例如获取RGB彩色图像image的[i,j]点的r,g,b三个分量,可采用:
Uchar*ptr=&CV_IMAGE_ELEM(image,uchar,i,j,3);
那么prt[0]、prt[1]、prt[2]就分别对应该点b,g,r三个分量。
例题4-7获取数组子集函数使用
(5)数学函数
intcvRound(doublevalue);取整
intcvFloor(doublevalue);向下取整
intcvCeil(doublevalue);向上取整
floatcvSqrt(floatvalue);计算平方根
floatcvInvSqrt(floatvalue);计算平方根的倒数
floatcvCbrt(floatvalue);计算立方根
floatcvFastArctan(floaty,floatx);计算二维向量的角度
intcvIsNaN(doublevalue);判断输入是否是一个数字
intcvIsInf(doublevalue);判断输入是否是无穷大
voidcvCartToPolar(constCvArr*x,constCvArr*y,CvArr*magnitude,CvArr*angle=NULL,intangle_in_degrees=0);计算二维向量的长度和/或者角度
voidcvPolarToCart(constCvArr*magnitude,constCvArr*angle,CvArr*x,CvArr*y,intangle_in_degrees=0);计算极坐标形式的二维向量对应的直角坐标
voidcvPow(constCvArr*src,CvArr*dst,doublepower);对数组内每个元素求幂
voidcvExp(constCvArr*src,CvArr*dst);计算数组元素的指数幂
voidcvLog(constCvArr*src,CvArr*dst);计算每个数组元素的绝对值的自然对数
(6)数组算术逻辑比较
voidcvConvertScale(constCvArr*src,CvArr*dst,doublescale=1,doubleshift=0);
使用线性变换转换数组,即:
dst(I)=src(I)*scale+(shift,shift,...),
voidcvAdd(constCvArr*src1,constCvArr*src2,CvArr*dst,constCvArr*mask=NULL);
计算两个数组中每个元素的和,即:
dst(I)=src1(I)+src2(I)ifmask(I)!
=0
voidcvAddS(constCvArr*src,CvScalarvalue,CvArr*dst,constCvArr*mask=NULL);
计算数量和数组中之间的和,即:
dst(I)=src1(I)+valueifmask(I)!
=0
voidcvAddWeighted(constCvArr*src1,doublealpha,constCvArr*src2,doublebeta,doublegamma,CvArr*dst);
计算两数组的加权值的和,即:
dst(I)=src1(I)*alpha+src2(I)*beta+gamma
voidcvSub(constCvArr*src1,constCvArr*src2,CvArr*dst,constCvArr*mask=NULL);
计算两个数组每个元素的差
voidcvSubS(constCvArr*src,CvScalarvalue,CvArr*dst,constCvArr*mask=NULL);
计算数组和数量之间的差dst(I)=src(I)–valueifmask(I)!
=0
voidcvSubRS(constCvArr*src,CvScalarvalue,CvArr*dst,constCvArr*mask=NULL);
计算数量和数组之间的差dst(I)=value-src(I)ifmask(I)!
=0
voidcvMul(constCvArr*src1,constCvArr*src2,CvArr*dst,doublescale=1);
计算两个数组中每个元素的积,即:
dst(I)=scale*src1(I)*src2(I)
voidcvDiv(constCvArr*src1,constCvArr*src2,CvArr*dst,doublescale=1);
两个数组每个元素相除,即:
dst(I)=scale*src1(I)/src2(I),ifsrc1!
=NULL
dst(I)=scale/src2(I),:
ifsrc1=NULL
voidcvAnd(constCvArr*src1,constCvArr*src2,CvArr*dst,constCvArr*mask=NULL);
计算两个数组的每个元素的按位与
voidcvAndS(constCvArr*src,CvScalarvalue,CvArr*dst,constCvArr*mask=NULL);
计算数组每个元素与数量之间的按位与