OpenCV矩阵操作

OpenCV矩阵操作
OpenCV矩阵操作

OpenCv矩阵操作

有很多函数有mask,代表掩码,如果某位mask是0,那么对应的src的那一位就不计算,mask要和矩阵/ROI/的大小相等

大多数函数支持ROI,如果图像ROI被设置,那么只处理ROI部分

少部分函数支持COI,如果COI设置,只处理感兴趣的通道

矩阵逻辑运算

void cvAnd(const CvArr* src1,const CvArr* src2, CvArr* dst, const CvArr* mask=NULL);// void cvAndS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);// void cvOr(const CvArr* src1, const CvArr* src2, CvArr* dst, constCvArr* mask=NULL);// void cvOrS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);// void cvXor(const CvArr* src1, const CvArr* src2, CvArr* dst, constCvArr* mask=NULL);// void cvXorS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);// void cvNot(const CvArr* src,CvArr* dst);//矩阵取反

矩阵算术运算绝对值

void cvAbs(const CvArr*src,CvArr* dst);

void cvAbsDiff(const CvArr* src1,const CvArr* src2, CvArr*dst);//两矩阵相减取绝对值void cvAbsDiffS(const CvArr* src, CvArr* dst,CvScalarvalue);//矩阵减去一个数取绝对值加减

void cvAdd(const CvArr* src1,const CvArr*src2,CvArr* dst,const CvArr* mask =NULL);//两数组相加,dst(I)=src1(I)+src2(I) if mask(I)!=0

void cvAddS(const CvArr* src,CvScalar value,CvArr*dst,const CvArr*mask = NULL);//数组和一个数相加,dst(I)=src(I)+value if mask(I)!=0

void cvAddWeighted(const CvArr* src1,double alpha,const CvArr*src2,double

beta,double gamma,CvArradded to each sum*dst);//带权相加相当于dst(x,y) = α ?

src1(x,y) + β ? src2(x,y) + γ

void cvSub(const CvArr* src1, const CvArr* src2, CvArr* dst, constCvArr* mask=NULL);//矩阵减法,dst(I)=src1(I)-src2(I) if mask(I)!=0

void cvSubS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);//矩阵减数,dst(I)=src(I)-value if mask(I)!=0

void cvSubRS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);//数减矩阵,dst(I)=value-src(I) if mask(I)!=0

乘除

void cvDiv(const CvArr* src1, constCvArr* src2, CvArr* dst,

doublescale=1);//scale*src1(i)/src2(i),如果src1=NULL,则计算scale/src2(i)

void cvMul(const CvArr* src1,const CvArr* src2,CvArr* dst,doublescale=1);//两矩阵元素之间的简单乘法,一般的矩阵点乘用cvGEMM();

次方

void cvPow(const CvArr* src, CvArr* dst,double power);//为每个src的数求power次方

指数

void cvExp(const CvArr* src, CvArr*dst);//dst(I)=EXP(src(I))

对数

void cvLog(const CvArr* src, CvArr*dst);//

线性代数计算加&乘

voidcvScaleAdd(const CvArr* src1, CvScalar scale, const CvArr* src2,CvArr* dst);//src1和scale的乘积加上src2

void cvCrossProduct(const CvArr* src1,const CvArr* src2,CvArr*dst);//计算两个3D向量(单通道)的叉乘运算

double cvDotProduct(const CvArr* src1, const CvArr*src2);//两个向量点乘

void cvGEMM(const CvArr* src1, const CvArr* src2, double alpha,const CvArr* src3, double beta, CvArr* dst, inttABC=0);//乘加运算的始祖

由通用乘加函数参与定义的两个具体宏

cvMatMul(const CvArr* src1,const CvArr* src2,CvArr* dst);

cvMatMulAdd(const CvArr* src1,const CvArr* src2,const CvArr*src3,CvArr* dst); CvScalar cvTrace(const CvArr* mat);//计算对角线上的元素和

变换

void cvTransform(const CvArr* src, CvArr*dst, const CvMat* transmat, const

CvMat*shiftvec=NULL);//dst=transmat · src + shiftvec

void cvPerspectiveTransform(const CvArr* src, CvArr* dst, constCvMat* mat);//把矩阵每个元素中三个通道当做一个矩阵,乘mat,mat是一个3×3或者4×4的转换矩阵

转置

void cvTranspose(const CvArr* src, CvArr*dst);

void cvMulTransposed(const CvArr* src, CvArr* dst, int order, constCvArr* delta=NULL, doublescale=1.0);//(src-delta)乘以它的转置再乘以scale

逆矩阵

double cvInvert(const CvArr* src,CvArr*dst,int method=CV_LU);//求原矩阵的逆矩阵,默认使用高斯消去法

方阵可逆的充要条件是|A|!=0

method取值为CV_LU高斯消去法(默认) CV_SVD奇异值分解SVD CV_SVD_SYM

对称矩阵的SVD

行列式

double cvDet(const CvArr*mat);//计算方阵行列式,一定是单通道的

小型方阵直接计算,大型方阵用高斯消去法计算

如果矩阵正定对称,用奇异值分解的方法解决cvSVD();

特征向量特征值

void cvEigenVV(CvArr* mat, CvArr*evects, CvArr* evals, doubleeps=0);//计算对称矩阵的特征值和特征向量,evects输出特征向量,evals输出特征值,eps雅可比方法停止参数

要求三个矩阵都是浮点类型,10×10以下该方法有效,20×20以上的矩阵不能计算出结果,为节约计算量,eps通常设为DBL_EPSILON(10^-15)

如果给定的矩阵是对称正定矩阵,那么考虑使用cvSVD();

协方差

void cvCalcCovarMatrix(const CvArr**vects, int count, CvArr* cov_mat, CvArr* avg, intflags);//给定一组大小和类型相同的向量,向量的个数,计算标记,输出协方差正阵和每个向量的平均值矩阵

CV_COVAR_NORMAL 普通计算协方差和平均值,输出的是n×n的协方差阵

CV_COVAR_SCRAMBLED 快速PCA“Scrambled”协方差,输出的是m×m的协方差阵 CV_COVAR_USE_AVERAGE 平均值是输入的

CV_COVAR_SCALE 重新缩放输出的协方差矩阵

四个flag通过并运算协同发挥作用,前两个不能并

CvSize cvMahalonobis(const CvArr* vec1,const CvArr* vec2,CvArr*mat);

int cvSolve(const CvArr* src1, const CvArr* src2, CvArr* dst, intmethod=CV_LU);//Solves a linear system or least-squaresproblem.

void cvSVD(CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, intflags=0);//Performs singular value decomposition of a realfloating-point matrix.

void cvSVBkSb(const CvArr* W, const CvArr* U, const CvArr* V, constCvArr* B, CvArr* X, int flags);//Performs singular value backsubstitution.

数组比较

void cvCmp(const CvArr* src1, constCvArr* src2, CvArr* dst, int cmp_op);//两矩阵比较运算

CV_CMP_EQ -src1(I) 是否相等

CV_CMP_GT -src1(I) 是否大于

CV_CMP_GE -src1(I) 是否大于等于

CV_CMP_LT -src1(I) 是否小于

CV_CMP_LE -src1(I) 是否小于等于

CV_CMP_NE -src1(I) 是否不等

如果判断为假,dst设为0,如果判断为真,dst设为0xff

void cvCmpS(const CvArr* src, double value, CvArr* dst, intcmp_op);//矩阵和一个数字比较运算

矩阵内转换类型转换

void cvConvertScale(constCvArr* src,CvArr* dst,double scale,doubleshift);//矩阵首先乘以scale再加上shift,然后把src中的数据类型转换成dst类型,但是src和dst通道数需要相等

void cvConvertScaleAbs(const CvArr* src,CvArr* dst,doublescale,double shift);//在src到dst类型转换前,先做绝对值

void cvCvtColor(const CvArr* src,CvArr* dst, int code);//图像颜色空间转换,src要为8U 16U 32F,dst的数据类型需要和src相同,通道数看code

code格式如:CV_原色彩空间2目的色彩空间色彩空间要考虑RGB的顺序

支持的颜色空间包括:

RGB RGB565 RGB555 GRAYRGBA XYZ YCrCb HSV HLS Luv BayerRG

空间转换

void cvFlip(const CvArr* src, CvArr*dst=NULL, intflip_mode=0);//图像绕x、y轴旋转。当用在一维数组上时并且flip_mode>0,可以用来颠倒数据排列

flip_mode=0:左右对称values of the conversion resul

flip_mode>0:上下对称

flip_mode<0:中心对称

矩阵间操作void cvCopy(const CvArr* src,CvArr*dst,const CvArr* mask=NULL);

void cvMerge(const CvArr* src0,const CvArr* src1,const CvArr*src2,const CvArr*

src3,CvArr*dst);//多个数组合并成一个,类型和尺寸都相同,dst有多个通道,src可以赋值NULL

void cvSplit(cosnt CvArr* src,CvArr* dst0,CvArr* dst1,CvArr*dst2,CvArr* dst3);//一个多通道数组分解成多个数组,类型尺寸都想同,dst可以赋值NULL

void cvRepeat(const CvArr* src, CvArr*dst);//在dst中重复叠加src,dst(i,j)=src(i mod rows(src), j modcols(src))

CvMat* cvReshape(const CvArr* originalarr, CvMat* headerdata, intnew_cn,

intnew_rows=0);//把一个originalarr(可以是已经有内容的图片),转换为有新的通道数、新的行数的数据(CvMat*只含数据,没有图片头)

CvArr* cvReshapeMatND(const CvArr* arr, int sizeof_header, CvArr*header, int new_cn, int new_dims, int* new_sizes);

void cvLUT(const CvArr* src, CvArr* dst, const CvArr*lut);//src是8bit类型的数据,lut是一张一维查找表,拥有256个通道数类型和dst相同的元素,src的某一位置的元素数值n,到lut的n位置查找的内容填入dst的相应src的n元素的位置

统计运算最大最小

void cvMax(const CvArr* src1,const CvArr* src2, CvArr* dst);

void cvMaxS(const CvArr* src, double value, CvArr*dst);//找较大值放到dst中

void cvMin(const CvArr* src1,const CvArr* src2,CvArr* dst);

void cvMins(const CvArr* src,double value,CvArr*dst);//找较小值放到dst中

void cvMinMaxLoc(const CvArr* arr, double* min_val, double*max_val, CvPoint*

min_loc=NULL, CvPoint* max_loc=NULL, const CvArr*mask=NULL);

找出全局某个通道中最大最小的值,和她们的位置,如果不止一个通道,一定要设置COI 零的个数

int cvCountNonZero( const CvArr* arr);//统计非零的个数

是否落在范围内

void cvInRange(const CvArr*src,const CvArr* lower,const CvArr* upper,CvArr* dst);

void cvInRangeS(const CvArr* src,CvScalar lower,CvScalarupper,CvArr* dst);//判断原数组中的每个数大小是否落在对应的lower、upper数组位置数值的中间

if(lower(i)<=src(i)

平均值标准差

CvScalar cvAvg(const CvArr* arr,constCvArr* mask =NULL);//计算mask非零位置的所有元素的平均值,如果是图片,则单独计算每个通道上的平均值,如果COI设置了,只计算该COI通道的平均值

void cvAvgSdv(const CvArr* arr, CvScalar* mean, CvScalar* std_dev,const CvArr*

mask=NULL);//计算各通道的平均值,标准差,支持COI

double cvNorm(const CvArr* arr1,const CvArr* arr2=NULL,intnorm_type=CV_L2,const CvArr* mask=NULL);//计算一个数组的各种范数

如果arr2为NULL,norm_type为

CV_C 求所有数取绝对值后的最大值,CV_L1 求所有数的绝对值的和,CV_L2求所有数的平方和的平方根

如果arr2不为NULL,norm_type为

CV_Carr1和arr2对应元素差的绝对值中的最大值 CV_L1arr1和arr2对应元素差的绝对值的和 CV_L2 arr1和arr2的差平方和的平方根

CV_RELATIVE_C CV_RELATIVE_L1 CV_RELATIVE_L2 上面结果除以

cvNorm(arr2,NULL,对应的norm_type);

cvNormalize(const CvArr* src,CvArr* dst,double a=1.0,doubleb=0.0,int

norm_type=CV_L2,const CvArr* mask=NULL);

CV_C CV_L1 CV_L2 CV_MINMAX

cvReduce(const CvArr* src,CvArr* dst,int dim,intop=CV_REDUCE_SUM);//根据一定规则,把矩阵约简为向量

dim 决定约简到行还是列 1:约简到单个列,0:约简到单个行,-1:根据dst的CvSize,

决定约简到行还是列

op 决定按什么规则约简

CV_REDUCE_SUM - 行/列的和

CV_REDUCE_AVG- 行/列平均值

CV_REDUCE_MAX - 行/列中最大值

CV_REDUCE_MIN- 行/列中最小值

取得设置数组信息得到指定行列

CvMat* cvGetCol(constCvArr* arr,CvMat* submat,int col);

CvMat* cvGetCols(const CvArr* arr,CvMat* submat,int start_col,intend_col);//取目标矩阵

的某列/连续几列,submat和返回值的实际数据还是在原矩阵中,只是修改了头部和数据指针,没有数据拷贝

CvMat* cvGetRow(const CvArr* arr,CvMat* submat,int row);

CvMat* cvGetRows(const CvArr* arr,CvMat* submat,int start_row,intend_row);

得到对角线

CvMat* cvGetDiag(const CvArr*arr,CvMat* submat,intdiag=0);//取矩阵arr的对角线,结果放在向量中,并不要求原矩阵是方阵,diag表示从哪个位置开始取对角线

维度大小

int cvGetDims(const CvArr* arr,int*sizes=NULL);//获取数组的维数和每一维的大小,sizes

十一个数组的头指针。图像或者矩阵的维数一定是2,先行数后列数

int cvGetDimSize(const CvArr* arr,int index);//获取某一维的大小

矩阵大小

CvSize cvGetSize(const CvArr*arr);//返回矩阵和图像的大小。小的结构体一般都是直接返

回值而不是重新分配指针,分配指针的效率可能比直接返回值效率更低

截取矩形矩阵

CvMat* cvGetSubRect(const CvArr* arr,CvMat* submat, CvRectrect);//从输入的数组中根

据输入的矩形截取一块数组中的矩形,返回的CvMat*就是submat

得到和设置元素因为效率原因,实际很少会直接用到这些方法,而是根据实际的应用来决定如何操作每一个数

uchar* cvPtr1D(CvArr* arr,int idx0,int*type);//得到的是指针,所以可以修改,比下面的效率

更高

uchar* cvPtr2D(CvArr* arr,int idx0,int idx1,int* type);

uchar* cvPtr3D(CvArr* arr,int idx0,int idx1,int idx2,int*type);

uchar* cvPtrND(CvArr* arr,int* idx,int* type,intcreate_node=1,unsigned*

precalc_hashval=NULL);//int*idx是一个数组指针,里面保存着索引

double cvGetReal1D(const CvArr* arr,int idx0);//得到的是具体值

double cvGetReal2D(const CvArr* arr,int idx0,int idx1);

double cvGetReal3D(const CvArr* arr,int idx0,int idx1,intidx2);

double cvGetRealND(const CvArr* arr,int* idx);

CvScalar cvGet1D(const CvArr* arr,int idx0);

CvScalar cvGet2D(const CvArr* arr,int idx0,int idx1);

CvScalar cvGet3D(const CvArr* arr,int idx0,int idx1,intidx2);

CvScalar cvGetND(const CvArr* arr,int* idx);

double cvmGet(const CvMat* mat, int row, intcol);//仅仅用于矩阵单通道浮点数的获取,由于是inline并且没有类型判断,所以效率比较高

void cvSetReal1D(CvArr* arr, int idx0, double value);

void cvSetReal2D(CvArr* arr, int idx0, int idx1, doublevalue);

void cvSetReal3D(CvArr* arr, int idx0, int idx1, int idx2, doublevalue);

void cvSetRealND(CvArr* arr, int* idx, double value);

void cvSet1D(CvArr* arr, int idx0, CvScalar value);

void cvSet2D(CvArr* arr, int idx0, int idx1, CvScalar value);

void cvSet3D(CvArr* arr, int idx0, int idx1, int idx2, CvScalarvalue);

void cvSetND(CvArr* arr, int* idx, CvScalar value);

void cvmSet(CvMat* mat, int row, int col, doublevalue);//仅仅用于设置单通道浮点类型的矩阵

void cvClearND(CvArr* arr, int* idx);//把多维数组的某位置设置为0

void cvSet(CvArr* arr, CvScalar value, const CvArr*mask=NULL);//把数组每个元素都设为value

void cvSetZero(CvArr* arr);//对普通矩阵,每位都设为0;对稀疏矩阵,删除所以元素

一般算数运算int cvRound(double value ); int cvFloor(double value ); int

cvCeil( doublevalue);//求和double最(上/下)接近的整数

float cvSqrt(float value);//求平方根

float cvInvSqrt(float value);//求平方根倒数

float cvCbrt(float value);//求立方根

float cvCbrt(float value);//求两个向量的夹角

int cvIsNaN(double value);//判断是否是合法数

int cvIsInf(double value);//判断是否无穷

void cvCartToPolar(const CvArr* x, const CvArr* y, CvArr*magnitude, CvArr* angle=NULL, int angle_in_degrees=0);//

void cvPolarToCart(const CvArr* magnitude, const CvArr* angle,CvArr* x, CvArr* y, int angle_in_degrees=0);//

void cvSolveCubic(const CvArr* coeffs, CvArr*roots);//求三次方方程解,coeffs作为三次方程的系数,可以是三元(三次方系数为1)或者四元

随机数生成CvRNG cvRNG(int64seed=-1);//生成随机数生成器

unsigned cvRandInt(CvRNG* rng);

double cvRandReal(CvRNG* rng);

void cvRandArr(CvRNG* rng, CvArr* arr, int dist_type, CvScalarparam1, CvScalar

param2);//

dist_type决定生成随机数组中的分布 CV_RAND_UNI均匀分布 CV_RAND_NORMAL 正态/高斯分布

param1:均匀分布中的下界(包含),正态分布中的平均值

param2:均匀分布中的上界(不包含),正态分布中的偏差

分布转换

void cvDFT(const CvArr* src, CvArr*dst, int flags, int nonzero_rows=0);

int cvGetOptimalDFTSize(int size0);

void cvMulSpectrums(const CvArr* src1, const CvArr* src2, CvArr*dst, int flags);

void cvDCT(const CvArr* src, CvArr* dst, int flags);

转载:https://www.360docs.net/doc/754969351.html,/????????/blog/item/f660c31409559a09972b43ee.html

在OpenCV中有三种方式访问矩阵中的数据元素:容易的方式,困难的方式,以及正确的方式。以下先讲容易的方式和困难的方式。

容易的方式

最容易的方式是使用宏CV_MAT_ELEM( matrix, elemtype, row, col ),输入参数是矩阵的指针,矩阵元素类型,行,列,返回值是相应行,列的矩阵元素,例如:

CvMat* mat = cvCreateMat(5,5,CV_32FC1);

float element = CV_MAT_ELEM(*mat,float,3,2);

以下是一个例子:

#pragma comment( lib, "cxcore.lib" )

#include "cv.h"

#include

void main()

{

CvMat* mat = cvCreateMat(3,3,CV_32FC1);

cvZero(mat);//将矩阵置0

//为矩阵元素赋值

CV_MAT_ELEM( *mat, float, 0, 0 ) = 1.f;

CV_MAT_ELEM( *mat, float, 0, 1 ) = 2.f;

CV_MAT_ELEM( *mat, float, 0, 2 ) = 3.f;

CV_MAT_ELEM( *mat, float, 1, 0 ) = 4.f;

CV_MAT_ELEM( *mat, float, 1, 1 ) = 5.f;

CV_MAT_ELEM( *mat, float, 1, 2 ) = 6.f;

CV_MAT_ELEM( *mat, float, 2, 0 ) = 7.f;

CV_MAT_ELEM( *mat, float, 2, 1 ) = 8.f;

CV_MAT_ELEM( *mat, float, 2, 2 ) = 9.f;

//获得矩阵元素的值

float element = CV_MAT_ELEM(*mat,float,2,2);

printf("%f/n",element);

}

CV_MAT_ELEM宏实际上会调用CV_MAT_ELEM_PTR(matrix,row,col)宏来完成任务。CV_MAT_ELEM_PTR()宏的参数是矩阵的指针,行,列。

CV_MAT_ELEM()宏和CV_MAT_ELEM_PTR()宏的区别是,在调用CV_MAT_ELEM时,指向矩阵元素的指针的数据类型已经依据输入参数中的元素类型而

做了强制转换。,以下是使用CV_MAT_ELEM_PTR()来设置元素的值:

#pragma comment( lib, "cxcore.lib" )

#include "cv.h"

#include

void main()

{

CvMat* mat = cvCreateMat(3,3,CV_32FC1);

cvZero(mat);//将矩阵置0

float element_0_2 = 7.7f;

*((float*)CV_MAT_ELEM_PTR( *mat, 0, 2 ) ) = element_0_2;

//获得矩阵元素的值

float element = CV_MAT_ELEM(*mat,float,0,2);

printf("%f/n",element);

}

以上使用矩阵中元素的方式很方便,但不幸的是,该宏在每次调用时,都会重新计算指针的位置。这意味着,先查找矩阵数据区中第0个元素的位置,然后,根据参数中的行和列,计算所需要的元素的地址偏移量,然后将地址偏移量与第0个元素的地址相加,获得所需要的元素的地址。

所以,以上的方式虽然很容易使用,但是却不是获得矩阵元素的最好方式。特别是当你要顺序遍历整个矩阵中所有元素时,这种每次对地址的重复计算就更加显得不合理。

困难的方式

以上两个宏只适合获得一维或二维的矩阵(数组)元素,OpenCV提供了处理多维矩阵(数组)的方式。实际上你可以不受限制地使用N维。

当访问这样一种N维矩阵中元素时,你需要使用一个系列的函数,叫做cvPtr*D,*代表

1,2,3,4....,例如,cvPtr1D(),cvPtr2D(),cvPtr3D(),以及cvPtrND().以下为此系列函数的定义:

cvPtr*D函数用于返回指向某数组元素的指针

uchar* cvPtr1D( const CvArr* arr, int idx0, int* type=NULL );

uchar* cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type=NULL );

uchar* cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL );

uchar* cvPtrND( const CvArr* arr, int* idx, int* type=NULL, int create_node=1, unsigned* precalc_hashval=NULL );

arr

输入数组(矩阵).

idx0

元素下标的第一个以0为基准的成员

idx1

元素下标的第二个以0为基准的成员

idx2

元素下标的第三个以0为基准的成员

idx

数组元素下标

type

可选的,表示输出参数的数据类型

create_node

可选的,为稀疏矩阵输入的参数。如果这个参数非零就意味着被需要的元素如果不存在就会被创建。

precalc_hashval

可选的,为稀疏矩阵设置的输入参数。如果这个指针非NULL,函数不会重新计算节点的HASH值,而是从指定位置获取。这种方法有利于提高智能组合数据的操作

函数cvPtr*D 返回指向特殊数组元素的指针。数组维数应该与传递给函数的下标数相匹配,它可以被用于顺序存取的1D,2D或nD密集数组

函数也可以用于稀疏数组,并且如果被需要的节点不存在函数可以创建这个节点并设置为0 就像其它获取数组元素的函数(cvGet[Real]*D, cvSet[Real]*D)如果元素的下标超出了范围就会产生错误

很明显,如果是一维数组(矩阵),那就可以使用cvPtr1D,用参数idx0来指向要获得的第idx0个元素,返回值为指向该元素的指针,如果是二维数组(矩阵),就可以使用cvPtr2D,用idx0,idx1来指向相应的元素。

如果是N维数组,则int* idx参数指向对N维数组中某元素定位用的下标序列。

#pragma comment( lib, "cxcore.lib" )

#include "cv.h"

#include

void main()

{

CvMat* mat = cvCreateMat(3,3,CV_32FC1);

cvZero(mat);//将矩阵置0

//为矩阵元素赋值

CV_MAT_ELEM( *mat, float, 0, 0 ) = 1.f;

CV_MAT_ELEM( *mat, float, 0, 1 ) = 2.f;

CV_MAT_ELEM( *mat, float, 0, 2 ) = 3.f;

CV_MAT_ELEM( *mat, float, 1, 0 ) = 4.f;

CV_MAT_ELEM( *mat, float, 1, 1 ) = 5.f;

CV_MAT_ELEM( *mat, float, 1, 2 ) = 6.f;

CV_MAT_ELEM( *mat, float, 2, 0 ) = 7.f;

CV_MAT_ELEM( *mat, float, 2, 1 ) = 8.f;

CV_MAT_ELEM( *mat, float, 2, 2 ) = 9.f;

//获得矩阵元素(0,2)的值

float *p = (float*)cvPtr2D(mat, 0, 2);

printf("%f/n",*p);

}

我们使用cvPtr*D()函数的一个理由是,通过此函数,我们可以用指针指向矩阵中的某元素,并使用指针运算符,来设置该元素的值,或者,用指针运算来移动指针,指向从起始位置开始的矩阵中的其他元素。例如,我们可以用以下方式遍历矩阵中的元素:

#pragma comment( lib, "cxcore.lib" )

#include "cv.h"

#include

void main()

{

CvMat* mat = cvCreateMat(3,3,CV_32FC1);

cvZero(mat);//将矩阵置0

//获得矩阵元素(0,0)的指针

float *p = (float*)cvPtr2D(mat, 0, 0);

//为矩阵赋值

for(int i = 0; i < 9; i++)

{

*p = (float)i;

p++;

}

//打印矩阵的值

p = (float*)cvPtr2D(mat, 0, 0);

for(i = 0; i < 9; i++)

{

printf("%f/t",*p);

p++;

if((i+1) % 3 == 0)

printf("/n");

}

}

但是要注意,以上为矩阵中元素的通道数为1时,可以用p++来访问下一个矩阵中元素,但是如果通道数不为1,例如一个三通道的二维矩阵,矩阵中每个元素的值为RGB值,则矩阵中数据按以下方式存储:rgbrgbrgb......,因此,使用指针指向下一个元素时,就需要加上相应的通道数。

举例如下:

#pragma comment( lib, "cxcore.lib" )

#include "cv.h"

#include

void main()

{

//矩阵元素为三通道浮点数

CvMat* mat = cvCreateMat(3,3,CV_32FC3);

cvZero(mat);//将矩阵置0

//为矩阵元素赋值

//获得矩阵元素(0,0)的指针

float *p = (float*)cvPtr2D(mat, 0, 0);

//为矩阵赋值

for(int i = 0; i < 9; i++)

{

//为每个通道赋值

*p = (float)i*10;

p++;

*p = (float)i*10+1;

p++;

*p = (float)i*10+2;

p++;

}

//打印矩阵的值

p = (float*)cvPtr2D(mat, 0, 0);

for(i = 0; i < 9; i++)

{

printf("%2.1f,%2.1f,%2.1f/t",*p,*(p+1),*(p+2));

p+=3;

if((i+1) % 3 == 0)

printf("/n");

}

}

如果你不想使用指向数据的指针,而只是想获得矩阵中的数据,你还可以使用cvGet*D函数系列。如下所示,该函数系列以返回值类型划分有两种,一种返回double类型数据,另一种返回CvScalar类型数据。

Get*D返回特殊的数组元素

CvScalar cvGet1D( const CvArr* arr, int idx0 );

CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );

CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );

CvScalar cvGetND( const CvArr* arr, int* idx );

arr输入数组.

idx0元素下标第一个以0为基准的成员

idx1元素下标第二个以0为基准的成员

idx2元素下标第三个以0为基准的成员

idx元素下标数组

函数cvGet*D 返回指定的数组元素。对于稀疏数组如果需要的节点不存在函数返回0 (不会创建新的节点)

GetReal*D返回单通道数组的指定元素

double cvGetReal1D( const CvArr* arr, int idx0 );

double cvGetReal2D( const CvArr* arr, int idx0, int idx1 );

double cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );

double cvGetRealND( const CvArr* arr, int* idx );

arr输入数组,必须是单通道.

idx0元素下标的第一个成员,以0为基准

idx1元素下标的第二个成员,以0为基准

idx2元素下标的第三个成员,以0为基准

idx

元素下标数组

函数cvGetReal*D 返回单通道数组的指定元素,如果数组是多通道的,就会产生运行时错误,而cvGet*D 函数可以安全的被用于单通道和多通道数组,注意,该方法返回值类型是double类型的,这意味着,矩阵中如果保存的是int类型数据,不能用此系列方法。

#pragma comment(lib,"cxcore.lib")

#include"cv.h"

#include

void main()

{

//矩阵元素为1通道浮点型数据

CvMat*mat=cvCreateMat(3,3,CV_32FC1 );

cvZero(mat);//将矩阵置0

//为矩阵元素赋值

//获得矩阵元素(0,0)的指针

float *p=(float*)cvPtr2D(mat,0,0);

//为矩阵赋值

for(int i=0;i<9;i++)

{

//为每个通道赋值

*p=(float)i*10;

p++;

}

for(i=0;i<3;i++)

for(int j=0;j<3;j++)

{

printf("%lf/t",cvGetReal2D(mat,i,j));

}

}

另外,我们还有类似于cvGet*D()的方法为矩阵元素赋值:cvSetReal*D()和cvSet*D()。Set*D

修改指定的数组

void cvSet1D( CvArr* arr, int idx0, CvScalar value );

void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );

void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );

void cvSetND( CvArr* arr, int* idx, CvScalar value );

arr

输入数组

idx0

元素下标的第一个成员,以0为基点

idx1

元素下标的第二个成员,以0为基点

idx2

元素下标的第三个成员,以0为基点

idx

元素下标数组

value

指派的值

函数cvSet*D 指定新的值给指定的数组元素。对于稀疏矩阵如果指定节点不存在函数创建新的节点

SetReal*D

修改指定数组元素值

void cvSetReal1D( CvArr* arr, int idx0, double value );

void cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );

void cvSetReal3D( CvArr* arr, int idx0, int idx1, int idx2, double value );

void cvSetRealND( CvArr* arr, int* idx, double value );

arr

输入数组.

idx0

元素下标的第一个成员,以0为基点

idx1

元素下标的第二个成员,以0为基点

idx2

元素下标的第三个成员,以0为基点

idx

元素下标数组

value

指派的值

函数cvSetReal*D 分配新的值给单通道数组的指定元素,如果数组是多通道就会产生运行

时错误。然而cvSet*D 可以安全的被用于多通道和单通道数组。

对于稀疏数组如果指定的节点不存在函数会创建该节点。

以下是一个例子:

#pragma comment(lib,"cxcore.lib")

#include"cv.h"

#include

void main()

{

//矩阵元素为三通道8位浮点数

CvMat *mat=cvCreateMat(3,3,CV_32FC3 );

cvZero(mat);//将矩阵置0

//为矩阵元素赋值

for(int i = 0; i < 3; i++)

for(int j = 0; j < 3; j++)

cvSet2D( mat, i, j, cvScalar(i*10,j*10,i*j*10) );

for(i=0;i<3;i++)

for(int j=0;j<3;j++)

{

printf("%lf,%lf,%lf/t",cvGet2D( mat, i, j ).val[0],cvGet2D( mat, i, j ).val[1],cvGet2D( mat, i, j ).val[2]);

}

}

为了方便起见,OpenCV还定义了两个函数:cvmSet()和cvmGet(),这两个函数用于单通道浮点型元素矩阵的存取。

例如,cvmSet(mat,2,2,0.5);就类似于cvSetReal2D(mat,2,2,0.5);

返回单通道浮点矩阵指定元素

double cvmGet( const CvMat* mat, int row, int col );

为单通道浮点矩阵的指定元素赋值。

void cvmSet( CvMat* mat, int row, int col, double value );

Opencv文件操作与数据存储

数据存储 OpenCV提供了一种机制来序列化(serialize)和去序列化(de-serialize)其各种数据类型,可以从磁盘中按YAML或XML格式读/写。在第4章中,我们将专门介绍存储和调用常见的对象IplImages的函数(cvSaveImage()和cvLoadImage())。此外,第4章将讨论读/写视频的特有函数:可以从文件或者摄影机中读取数据的函数cvGrabFrame()以及写操作函数cvCreateVideoWriter()和cvWriteFrame()。本小节将侧重于一般对象的永久存储:读/写矩阵、OpenCV结构、配置与日志文件。 首先,我们从有效且简便的OpenCV矩阵的保存和读取功能函数开始。函数是cvSave()和cvLoad()。例3-15展示了如何保存和读取一个5×5的单位矩阵(对角线上是1,其余地方都是0)。 例3-15:存储和读取CvMat 1.CvMat A= cvMat( 5, 5, CV_32F, the_matrix_data ); 2. 3.cvSave( "my_matrix.xml", &A ); 4.. . . 5.// to load it then in some other program use … 6.CvMat* A1= (CvMat*) cvLoad( "my_matrix.xml" ); CxCore参考手册中有整节内容都在讨论数据存储。首先要知道,在OpenCV中,一般的数据存储要先创建一个CvFileStorage结构(如例3-16)所示,该结构将内存对象存储在一个树形结构中。然后通过使用 CV_STORAGE_READ参数的cvOpenFileStorage()从磁盘读取数据,创建填充该结构,也可以通过使用 CV_STORAGE_WRITE的cvOpenFileStorage()创建并打开CvFileStorage写数据,而后使用适当的数据存储函数来填充它。在磁盘上,数据的存储格式为XML或者YAML。 例3-16:CvFileStorage结构,数据通过CxCore数据存储函数访问 1.typedef struct CvFileStorage 2.{ 3.... // hidden fields 4.} CvFileStorage; CvFileStorage树内部的数据是一个层次化的数据集合,包括标量、CxCore对象(矩阵、序列和图)以及用户定义的对象。 假如有一个配置文件或日志文件。配置文件告诉我们视频有多少帧(10),画面大小(320×240)并且将应用一个3×3的色彩转换矩阵。例3-17展示了如何从磁盘中调出cfg.xml文件。 例3-17:往磁盘上写一个配置文件cfg.xml 1.CvFileStorage* fs= cvOpenFileStorage( 2."cfg.xml", 3.0, 4.CV_STORAGE_WRITE 5.); 6.cvWriteInt( fs, "frame_count", 10 ); 7.cvStartWriteStruct( fs, "frame_size", CV_NODE_SEQ ); 8.cvWriteInt( fs, 0, 320 ); 9.cvWriteInt( fs, 0, 200 ); 10.cvEndWriteStruct(fs); 11.cvWrite( fs, "color_cvt_matrix", cmatrix );

OpenCV主要函数介绍

4.1 OpenCV主要函数介绍 1) cvLoadImage 从文件中读取图像 IplImage* cvLoadImage(const char* filename,int flags=CV_LOAD_IMAGE_COLOR ); 函数cvLoadImage从指定文件读入图像,返回读入图像的指针。其中filename是要被读入的文件的文件名;flags指定读入图像的颜色和深度。 2)cvSaveImage 保存图像到文件 int cvSaveImage( const char* filename, const CvArr* image ); 函数cvSaveImage保存图像到指定文件。其中filename保存文件名。image 要保存的图像。图像格式的的选择依赖于filename的扩展名,只有8位单通道或者3通道(通道顺序为'BGR' )可以使用这个函数保存。 3)cvQueryFrame从摄像头或者文件中抓取并返回一帧 IplImage* cvQueryFrame( CvCapture* capture ); 函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。返回的图像不可以被用户释放或者修改。其中capture视频获取结构。。 4)cvCaptureFromCAM 初始化摄像头 CvCapture* cvCaptureFromCAM( int index ); 函数cvCaptureFromCAM给从摄像头的视频流分配和初始化CvCapture结构。 其中index要使用的摄像头索引。如果只有一个摄像头或者用哪个摄像头也无所谓,那使用参数-1应该便可以。 5)cvHaarDetectObjects 用来检测图像中的人脸区域 CV API(CvSeq*) cvHaarDetectObjects( const CvArr* image, CvHaarClassifierCascade* cascade, CvMemStorage* storage, double scale_factor CV_DEFAULT(1.1), int min_neighbors CV_DEFAULT(3), int flags CV_DEFAULT(0), CvSize min_size CV_DEFAULT(cvSize(0,0)), CvSize max_size CV_DEFAULT(cvSize(0,0))); 用于快速检测人脸区域,便于提取得到人脸数据。其中image 为被检图像,cascade为 haar分类器级联的内部标识形式,storage 为用来存储检测到的一

OPENCV函数

Opencv函数 分配图像空间: IplImage*cvCreateImage(CvSize size,int depth,int channels); size:cvSize(width,height); depth:IPL_DEPTH_8U,IPL_DEPTH_8S,IPL_DEPTH_16U, IPL_DEPTH_16S,IPL_DEPTH_32S,IPL_DEPTH_32F, IPL_DEPTH_64F channels:1,2,3or4. 注意数据为交叉存取.彩色图像的数据编排为b0g0r0b1g1 r1... 举例: //分配一个单通道字节图像 IplImage*img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); //分配一个三通道浮点图像 IplImage*img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); 释放图像空间: IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); cvReleaseImage(&img); 复制图像: IplImage*img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); IplImage*img2; img2=cvCloneImage(img1); 设定/获取兴趣区域: void cvSetImageROI(IplImage*image,CvRect rect); void cvResetImageROI(IplImage*image); vRect cvGetImageROI(const IplImage*image); 大部分OpenCV函数都支持ROI. 设定/获取兴趣通道: void cvSetImageCOI(IplImage*image,int coi);//0=all int cvGetImageCOI(const IplImage*image); 大部分OpenCV函数暂不支持COI.

OPenCV3.2中Mat对象常用函数属性总结

OPenCV3.2中Mat对象常用函数属性总结Mat对象是OpenCV2.0之后引进的图像数据结构,它能自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分。 在使用Mat对象时,有以下四个要点需要注意: 1、输出图像的内存是自动分配的 2、使用OpenCV的C++接口,不需要考虑内存分配问题 3、赋值操作和拷贝构造函数只会复制头部分 4、使用clone与copyTo两个函数实现数据完全复制 下面我们就具体介绍一下公共成员函数和公共属性。 公共成员函数: 1、cv::Mat::Mat ( int rows, int cols, int type ) 参数: rows2D数组中的行数 cols2D数组中的列数。 type数组类型。使用CV_8UC1,…,CV_64FC4创建1 - 4通道矩阵,或CV_8UC(n),…,CV_64FC(n)创建多通道(向上到CV_CN_MAX通道)矩阵。

2、cv::Mat::Mat ( Size size, int type ) 参数: size 2D数组大小:Size(cols, rows)。在Size()构造函数中,行数和列数以相反的顺序排列。 type 数组类型。使用CV_8UC1,…,CV_64FC4创建1 - 4通道矩阵,或CV_8UC(n),…,CV_64FC(n)创建多通道(向上到CV_CN_MAX通道)矩阵。 3、cv::Mat::Mat ( int rows, int cols, int type, const Scalar & s ) 参数: rows2D数组中的行数。 cols 2D数组中的列数。 type数组类型。使用CV_8UC1,…,CV_64FC4创建1 - 4通道矩阵,或CV_8UC(n),…,CV_64FC(n)创建多通道(向上到CV_CN_MAX通道)矩阵。s 初始化每个矩阵元素的可选值。在构建后将所有矩阵元素设置为特定值, 使用赋值运算符Mat::operator=(const Scalar& value) 。 4、cv::Mat::Mat ( Size size, int type,

OPENCV_Mat类存取方法(元素访问)

Opencv ----Mat类 ?cv::Mat ?depth/dims/channels/step/data/elemSize Mat矩阵中数据元素的地址计算公式: addr(M i0,i1,…i m-1) = M.data + M.step[0] * i0 + M.step[1] * i1+ … + M.step[m-1] * i m-1。其中m = M.dims 是指M的维度 i.data:Mat对象中的一个指针,指向内存中存放矩阵数据的一块内存(uchar* data). ii.row: 行;col:列;rows:行数;cols:列数。 iii.dims :Mat所代表的矩阵的维度,如3 * 4 的矩阵为2 维,3 * 4 * 5 的为3维. iv.channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说3 * 4 矩阵中一共12 个元素,如果每个元素有三个值,那么就说这个矩阵是3 通道的,即channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。但是opencv用imread(opencv读图的函数)读进来的图像,三通道存放顺序为B、 G、R。 v.depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个0 –6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };可见0和1都代表8位,2和3都代表16位,4和5代表32位,6代表64位; vi.step:是一个数组,定义了矩阵的布局,具体见下面图片分析,另外注意step1

opencv矩阵操作学习资料

o p e n c v矩阵操作

通用矩阵乘法 void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC=0 ); #define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( src1, src2, 1, src3, 1, dst, 0 ) #define cvMatMul( 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

所有的矩阵应该有相同的数据类型和协调的矩阵大小。支持实数浮点矩阵或者 复数浮点矩阵。 [编辑] Transform 对数组每一个元素执行矩阵变换 void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL ); src 输入数组 dst 输出数组 transmat 变换矩阵 shiftvec 可选偏移向量 函数 cvTransform 对数组 src 每一个元素执行矩阵变换并将结果存储到 dst: dst(I)=transmat*src(I) + shiftvec 或者 dst(I)k=sumj(transmat(k,j)*src(I)j) + shiftvec(k) N-通道数组 src 的每一个元素都被视为一个N元向量,使用一个M×N 的变换矩阵 transmat 和偏移向量 shiftvec 把它变换到一个 M-通道的数组 dst 的 一个元素中。这里可以选择将偏移向量 shiftvec 嵌入到 transmat 中。这样

opencv矩阵操作

通用矩阵乘法 void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC=0 ); #define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( src1, src2, 1, src3, 1, dst, 0 ) #define cvMatMul( 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

所有的矩阵应该有相同的数据类型和协调的矩阵大小。支持实数浮点矩阵或者复数浮点矩阵。 [编辑] Transform 对数组每一个元素执行矩阵变换 void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL ); src 输入数组 dst 输出数组 transmat 变换矩阵 shiftvec 可选偏移向量 函数 cvTransform 对数组 src 每一个元素执行矩阵变换并将结果存储到 dst: dst(I)=transmat*src(I) + shiftvec 或者 dst(I)k=sumj(transmat(k,j)*src(I)j) + shiftvec(k) N-通道数组 src 的每一个元素都被视为一个N元向量,使用一个M×N 的变换矩阵 transmat 和偏移向量 shiftvec 把它变换到一个 M-通道的数组 dst 的

Opencv中函数的用法

1、cvLoadImage:将图像文件加载至内存; 2、cvNamedWindow:在屏幕上创建一个窗口; 3、cvShowImage:在一个已创建好的窗口中显示图像; 4、cvWaitKey:使程序暂停,等待用户触发一个按键操作; 5、cvReleaseImage:释放图像文件所分配的内存; 6、cvDestroyWindow:销毁显示图像文件的窗口; 7、cvCreateFileCapture:通过参数设置确定要读入的AVI文件; 8、cvQueryFrame:用来将下一帧视频文件载入内存; 9、cvReleaseCapture:释放CvCapture结构开辟的内存空间; 10、cvCreateTrackbar:创建一个滚动条; 11、cvSetCaptureProperty:设置CvCapture对象的各种属性; 12、cvGetCaptureProperty:查询CvCapture对象的各种属性; 13、cvGetSize:当前图像结构的大小; 14、cvSmooth:对图像进行平滑处理; 15、cvPyrDown:图像金字塔,降采样,图像缩小为原来四分之一; 16、cvCanny:Canny边缘检测; 17、cvCreateCameraCapture:从摄像设备中读入数据; 18、cvCreateVideoWriter:创建一个写入设备以便逐帧将视频流写入视频文件;搜索 19、cvWriteFrame:逐帧将视频流写入文件; 20、cvReleaseVideoWriter:释放CvVideoWriter结构开辟的内存空间; 21、CV_MAT_ELEM:从矩阵中得到一个元素; 22、cvAbs:计算数组中所有元素的绝对值;

OpenCv矩阵操作函数源代码

/* //////////////////////////////////////////////////////////////////// // // CvMat, CvMatND, CvSparceMat and IplImage support functions // (creation, deletion, copying, retrieving and setting elements etc.) // // */ #include "_cxcore.h" static struct { Cv_iplCreateImageHeader createHeader; Cv_iplAllocateImageData allocateData; Cv_iplDeallocate deallocate; Cv_iplCreateROI createROI; Cv_iplCloneImage cloneImage; } CvIPL; // Makes the library use native IPL image allocators CV_IMPL void cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader, Cv_iplAllocateImageData allocateData, Cv_iplDeallocate deallocate, Cv_iplCreateROI createROI, Cv_iplCloneImage cloneImage ) { CV_FUNCNAME( "cvSetIPLAllocators" ); __BEGIN__; if( !createHeader || !allocateData || !deallocate || !createROI || !cloneImage ) { if( createHeader || allocateData || deallocate || createROI || cloneImage ) CV_ERROR( CV_StsBadArg, "Either all the pointers should be null or " "they all should be non-null" ); } CvIPL.createHeader = createHeader; CvIPL.allocateData = allocateData; CvIPL.deallocate = deallocate; CvIPL.createROI = createROI; CvIPL.cloneImage = cloneImage;

OPENCV的MAT类详解

类Mat导言 OpenCV c + + n 维稠密数组类 类CV_EXPORTS Mat { public: / / … …很多的方法... ... /*!包括几位字段: -神奇的签名 -连续性标志 -深度(Note:应该是位深) -通道数 */ int flags;(Note :目前还不知道flags做什么用的) //!数组的维数,> = 2 int dims ; //!行和列的数量或(-1,-1) 此时数组已超过2 维 int rows,cols; //!指向数据的指针 uchar *data ; //!指针的引用计数器; / / 阵列指向用户分配的数据时,当指针为NULL int * refcount ; / / 其他成员 ... }; Mat类表示一个n 维的密集数值单通道或多通道数组。它可以用于存储实数或复数值的向量和矩阵、灰度或彩色图像、体素、向量场、点云、张量、直方图(尽管较高维的直方图存储在SparseMat可能更好)。M 数组的数据布局是由阵列M.step[]定义的,使元素的地址(i0,。。。。i M.dims-1),其中0<= i k < M.size [k],可以计算为: addr( Mi0 ;:::;i M.dims-1) = M.data+ M.step[ 0]*i0 + M.step[ 1] *i1+ .…+ M.step[ M:dims- 1] i M:dims- 1 2维的数组的情况下根据上述公式被减至: addr( M i,j)= M.data+ M.step[ 0]*i+ M.step[ 1] *j

请注意,M.step[i] > =M.step[i+1] (事实上,M.step[i] > =M.step[i+1]*M.size[i+1])。这意味着2维矩阵是按行存储的,3 维矩阵是由平面存储,以此类推。M.step[M.dims-1] 是最小的而且总是等于元素大小M.elemSize()。因此,Mat中的数据布局完全兼容OpenCV 1.x 中CvMat、IplImage、CvMatND类型。它也和标准工具包和SDK,如Numpy(ndarray),Win32(独立设备位图)等主流的密集数组类型相兼容,也就是说,与任何使用步进(或步长)来计算像素位置的阵列相兼容。由于这种兼容性,使用户分配的数据创建Mat头以及用OpenCV函数实时处理该头成为可能。有很多不同的方法,创建一个Mat的对象。下面列出了最常见的选项: 使用create(nrows,ncols,type)方法或类似的Mat(nrows,ncols,type [,fillValue]) 构造函数。一个新的指定了大小和类型的数组被分配。type和cvCreateMat 方法中的type 参数具有相同的含义。例如,CV_8UC1 是指一个8 位单通道阵列,CV_32FC2 指 2 通道 (复)浮点阵列,以此类推。 //创建一个用1+3j填充的7 x 7 复矩阵。 Mat M(7,7,CV_32FC2,Scalar(1,3)) ; / /现在将M转换为100 x 60的CV_8UC(15)的矩阵。 / / 旧内容将会被释放 M.create(100,60,CV_8UC(15)) ; 这一章导言中指出,当当前的数组与指定的数组的形状或类型create() 分配唯一的新数组时的形状或类型。 创建多维数组: / / 创建100 x 100 x 100 8 位数组 int sz[] = {100, 100, 100}; Mat. bigCube (3,sz,CV_8U,Scalar::all(0)) ;它将维度数(= 1)传递给Mat的构造函数,但列数设置为1时,创建数组将是2 维的。因此,Mat::dims 始终是>=2的(该数组为空时,也可以是0)。 使用的复制构造函数或赋值运算符可以是一个数组或右侧的表达式(请参阅 下图)。正像在导言中指出的,数组赋值运算复杂度是O(1)因为当你需要它的时候,它仅复制头和增加引用计数。Mat::clone() 方法可用于获取全(深)的副本数组。 为另一个数组的一部分构建头。它可以是单个行、单个列,几个行,几个列,矩形区域(代数中称为较小值)的数组或对角线。这种操作也是复杂度为O(1),因为,新头引用相同的数据。实际上,您可以使用此特性修改该数组的一部分例如: / /第5行,乘以3,加到第3 行, M.row(3) = M.row(3) + M.row (5) * 3 ; / / 现在将第7列复制到第1列

OpenCV读取与操作摄像头

OpenCV读取摄像头 OpenCV可以读取摄像头的图像,主要是流媒体,读取的类是cv::VideoCapture,输入参数为摄像头参数: 当使用USB摄像头时,输入0,1,2…等对应参数 当使用网络摄像头时,直接输入url地址。 OpenCV设置属性 使用cv::VieoCapture时,先生成一个实例,然后设置属性,此时有一点 要注意,当读取的图片原本只有400*300时,设置高宽800*600是无效的(即 超过输入的尺寸设置是无效的),然后不断使用>>读取,读取就显示。 cv::VideoCapture capture; if(!capture.open(0)) { qDebug() << __FILE__ << __LINE__ << "Failed to open camera: 0"; }else{ qDebug() << __FILE__ << __LINE__ << "Succeed to open camera: 0"; } while(true) { cv::Mat mat; capture >> mat; int keyValue = cv::waitKey(1) } 同时经过测试发现,此次打开的是上次的设置结果,所以可以判断opencv 实际是直接操作了设备的相关属性,所以调整的属性需要摄像头设备支持(USB 摄像头),并不是单纯的认为拿到图片后opencv自己对图像进行处理。 Demo函数源码 void OpenCVManager::testCamera() { cv::VideoCapture capture; // 插入USB摄像头默认为0

opencv应用函数

目录 1 一、简介 1.1 1、OpenCV的特点 1.1.1 (1)总体描述 1.1.2 (2)功能 1.1.3 (3)OpenCV模块 1.2 2、有用的学习资源 1.2.1 (1)参考手册: 1.2.2 (2)网络资源: 1.2.3 (3)书籍: 1.2.4 (4)视频处理例程(在/samples/c/): 1.2.5 (5)图像处理例程(在/samples/c/): 1.3 3、OpenCV 命名规则 1.3.1 (1)函数名: 1.3.2 (2)矩阵数据类型: 1.3.3 (3)图像数据类型: 1.3.4 (4)头文件: 1.4 4、编译建议 1.4.1 (1)Linux: 1.4.2 (2)Windows: 1.5 5、C例程 2 二、GUI 指令 2.1 1、窗口管理 2.1.1 (1)创建和定位一个新窗口: 2.1.2 (2)载入图像: 2.1.3 (3)显示图像: 2.1.4 (4)关闭窗口: 2.1.5 (5)改变窗口大小: 2.2 2、输入处理 2.2.1 (1)处理鼠标事件: 2.2.2 (2)处理键盘事件: 2.2.3 (3)处理滑动条事件: 3 三、OpenCV的基本数据结构 3.1 1、图像数据结构 3.1.1 (1)IPL 图像: 3.2 2、矩阵与向量 3.2.1 (1)矩阵: 3.2.2 (2)一般矩阵: 3.2.3 (3)标量: 3.3 3、其它结构类型 3.3.1 (1)点:

3.3.2 (2)矩形框大小(以像素为精度): 3.3.3 (3)矩形框的偏置和大小: 4 四、图像处理 4.1 1、图像的内存分配与释放 4.1.1 (1)分配内存给一幅新图像: 4.1.2 (2)释放图像: 4.1.3 (3)复制图像: 4.1.4 (4)设置/获取感兴趣区域ROI: 4.1.5 (5)设置/获取感兴趣通道COI: 4.2 2、图像读写 4.2.1 (1)从文件中读入图像: 4.2.2 (2)保存图像: 4.3 3、访问图像像素 4.3.1 (1)假设你要访问第k通道、第i行、第j列的像素。 4.3.2 (2)间接访问: (通用,但效率低,可访问任意格式的图像) 4.3.3 (3)直接访问: (效率高,但容易出错) 4.3.4 (4)基于指针的直接访问: (简单高效) 4.3.5 (5)基于c++ wrapper 的直接访问: (更简单高效) 4.4 4、图像转换 4.4.1 (1)字节型图像的灰度-彩色转换: 4.4.2 (2)彩色图像->灰度图像: 4.4.3 (3)不同彩色空间之间的转换: 4.5 5、绘图指令 4.5.1 (1)绘制矩形: 4.5.2 (2)绘制圆形: 4.5.3 (3)绘制线段: 4.5.4 (4)绘制一组线段: 4.5.5 (5)绘制一组填充颜色的多边形: 4.5.6 (6)文本标注: 5 五、矩阵处理 5.1 1、矩阵的内存分配与释放 5.1.1 (1)总体上: 5.1.2 (2)为新矩阵分配内存: 5.1.3 (3)释放矩阵内存: 5.1.4 (4)复制矩阵: 5.1.5 (5)初始化矩阵: 5.1.6 (6)初始化矩阵为单位矩阵: 5.2 2、访问矩阵元素 5.2.1 (1)假设需要访问一个2D浮点型矩阵的第(i, j)个单元. 5.2.2 (2)间接访问: 5.2.3 (3)直接访问(假设矩阵数据按4字节行对齐): 5.2.4 (4)直接访问(当数据的行对齐可能存在间隙时possible alignment gaps):

OpenCV中对数组(矩阵)的操作的函数表

ALL ABOUT MY CODE AND MY LITTLE EMOTIONS 创建博客登录 网易 博客 发现小组风格登录新版LOFTER,送IMAX电影票 >加关注

OpenCV - Operations on Arrays 对数组(矩阵)的一些操作Function (函数名)Use (函数用处) Author : Ggicci 转载请注明出处!split 多通道矩阵分解成多个单通道矩阵merge 多个单通道矩阵合成一个多通道矩阵mixChannels 矩阵间通道拷贝,如Rgba[]到Rgb[]和Alpha[]sort, sortIdx 为矩阵的每行或每列元素排序setIdentity 设置单元矩阵completeSymm 矩阵上下三角拷贝inRange 检查元素的取值范围是否在另两个矩阵的元素取值之间,返回验证矩阵checkRange 检查矩阵的每个元素的取值是否在最小值与最大值之间,返回验证结果bool sum 求矩阵的元素和mean 求均值meanStdDev 均值和标准差countNonZero 统计非零值个数cartToPolar, polarToCart 笛卡尔坐标与极坐标之间的转换flip 矩阵翻转transpose 矩阵转置,比较 Mat::t() A T 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 矩阵和它自己的转置相乘 A T * 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 两个傅立叶频谱间逐元素的乘法 您可能也喜欢: OpenCV函数的参数用法(1 mask) 2012.07.21OpenCV中的结构体、类与Emgu.CV的2012.07.09

OpenCV矩阵操作

OpenCv矩阵操作 有很多函数有mask,代表掩码,如果某位mask是0,那么对应的src的那一位就不计算,mask要和矩阵/ROI/的大小相等 大多数函数支持ROI,如果图像ROI被设置,那么只处理ROI部分 少部分函数支持COI,如果COI设置,只处理感兴趣的通道 矩阵逻辑运算 void cvAnd(const CvArr* src1,const CvArr* src2, CvArr* dst, const CvArr* mask=NULL);// void cvAndS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);// void cvOr(const CvArr* src1, const CvArr* src2, CvArr* dst, constCvArr* mask=NULL);// void cvOrS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);// void cvXor(const CvArr* src1, const CvArr* src2, CvArr* dst, constCvArr* mask=NULL);// void cvXorS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);// void cvNot(const CvArr* src,CvArr* dst);//矩阵取反 矩阵算术运算绝对值 void cvAbs(const CvArr*src,CvArr* dst); void cvAbsDiff(const CvArr* src1,const CvArr* src2, CvArr*dst);//两矩阵相减取绝对值void cvAbsDiffS(const CvArr* src, CvArr* dst,CvScalarvalue);//矩阵减去一个数取绝对值加减 void cvAdd(const CvArr* src1,const CvArr*src2,CvArr* dst,const CvArr* mask =NULL);//两数组相加,dst(I)=src1(I)+src2(I) if mask(I)!=0 void cvAddS(const CvArr* src,CvScalar value,CvArr*dst,const CvArr*mask = NULL);//数组和一个数相加,dst(I)=src(I)+value if mask(I)!=0 void cvAddWeighted(const CvArr* src1,double alpha,const CvArr*src2,double beta,double gamma,CvArradded to each sum*dst);//带权相加相当于dst(x,y) = α ? src1(x,y) + β ? src2(x,y) + γ void cvSub(const CvArr* src1, const CvArr* src2, CvArr* dst, constCvArr* mask=NULL);//矩阵减法,dst(I)=src1(I)-src2(I) if mask(I)!=0 void cvSubS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);//矩阵减数,dst(I)=src(I)-value if mask(I)!=0 void cvSubRS(const CvArr* src, CvScalar value, CvArr* dst, constCvArr* mask=NULL);//数减矩阵,dst(I)=value-src(I) if mask(I)!=0 乘除 void cvDiv(const CvArr* src1, constCvArr* src2, CvArr* dst,

opencv二值化函数cvThreshold

opencv二值化函数cvThreshold OpenCV 2009-03-26 16:00:07 阅读4570 评论5 字号:大中小订阅 对图像二值化函数cvThreshold的理解 Threshold 对数组元素进行固定阈值操作 void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type ); src 原始数组 (单通道 , 8-bit of 32-bit 浮点数). dst 输出数组,必须与 src 的类型一致,或者为 8-bit. threshold 阈值 max_value 使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值. threshold_type 阈值类型 (见讨论) 函数 cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(cvCmpS 也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确定: threshold_type=CV_THRESH_BINARY: dst(x,y) = max_value, if src(x,y)>threshold 0, otherwise. threshold_type=CV_THRESH_BINARY_INV: dst(x,y) = 0, if src(x,y)>threshold; dst(x,y) = max_value, otherwise. threshold_type=CV_THRESH_TRUNC: dst(x,y) = threshold, if src(x,y)>threshold; dst(x,y) = src(x,y), otherwise. threshold_type=CV_THRESH_TOZERO: dst(x,y) = src(x,y), if (x,y)>threshold ; dst(x,y) = 0, otherwise.

OpenCV学习笔记

第一章概述 OpenCV 是有Intel公司资助的开源计算机视觉库,它由一系列C函数和少量C++类构成,实现图像处理和计算机视觉方面的很多通用算法。 1、OpenCV的特征 (1)开源计算机视觉库采用C/C++编写 (2)使用目的是开发实时的应用程序 (3)独立于操作系统、硬件和图形管理器 (4)具有通用的图像/视频载入、保存和获取模块 (5)具有底层和高层的应用开发包 2、OpenCV的功能 (1)对图像数据的操作,包括分配、释放、复制、设置和转换数据 (2)对图像和视频的输入输出,指文件和摄像头作为输入,图像和视频文件作为输出(3)具有对矩阵和向量的操作及线性代数的算法程序,包括矩阵积、解方程、特征值以及奇异值 (4)可对各种动态数据结构,如列表、队列、集合、树和图等进行操作 (5)具有基本的数字图像处理能力,如可以进行滤波、边缘检测、角点检测、采样于差值、色彩转换、形态操作、直方图和图像金字塔等操作 (6)对各种结构进行分析,包括连接部件分析、轮廓处理、距离变换、各种距的计算、模板匹配、Hough变换、多边行逼近、直线拟合、椭圆拟合、和Delaunay三角划分等 (7)对摄像头的定标,包括发现与跟踪定标模式、定标、基本矩阵估计、齐次矩阵估计和立体对应 (8)对运动的分析,如对光流、运动分割和跟踪的分析 (9)对目标的识别,如可采用特征法和隐马尔科夫模型(HMM)法 (10)具有基本的GUI功能,包括图像与视频显示、键盘和鼠标事件处理及滚动条等(11)课对图像标注,如对线,二次曲线和多边行进行标注 3.OpenCV模块 ?cv –核心函数库 ?cvaux –辅助函数库 ?cxcore –数据结构与线性代数库 ?highgui – GUI函数库 ?ml –机器学习函数库

相关主题
相关文档
最新文档