OpenCV基本数据类型
CvPoint
CvPoint2D32f
CvPoint3D32f
CvSize
CvSize2D32f
CvRect 派生于CvPoint 和 CvSize
CvScalar
typedef struct CvScalar
{
double val[4];
}
CvScalar;
(1) scalar:数量,数量的
(2) CvScalar有四个整型成员,可以用CvScalar代替1、2或3个实数成员,不需要的被忽略;有一个单独成员val,是一个指向四个双精度浮点数数组的指针
(3)CvScalar 的构造函数:cvScalar cvScalarAll cvRealScalar
矩阵和图像类型:
派生关系
CvArr
|
|__CvMat
|
|__IplImage
typedef struct CvMat
{
int type; /* CvMat signature (CV_MAT_MAGIC_VAL), element type and flags */
int step; /* full row length in bytes */
int* refcount; /* underlying data reference counter */
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data; /* data pointers */
#ifdef __cplusplus
union
{
int rows;
int height;
};
union
{
int cols;
int width;
};
#else
int rows; /* number of rows */
int cols; /* number of columns */
#endif
}
CvMat:矩阵结构
CvMat 构造函数:cvCreateMat()由cvCreateMatHeader()、cvCreateData构成
或cvCloneMat(CvMat*) 依据一个现有矩阵创建一个新的矩阵。可调用
cvReleaseMat(CvMat*)释放
矩阵的创建和释放
//Create a new rows by cols matrix of type “type”
CvMat* cvCreateMat(int rows,int cols,int type);
//Create only matirxs header without allocating data
CvMat* cvCreateMatHeader(int rows,int cols,int type);
//Initialize header on existing CvMat structure
CvMat* cvInitMatHeader(
CvMat* mat,
int rows,
int cols,
int type,
void* data = NULL,
int step = CV_AUTOSTEP);
//Like cvInitMatHeader() but allocates CvMat as well
CvMat cvMat(
int rows,
int cols,
int type,
void* data = NULL
);
//Allocate a new matrix just like the matrix ‘mat’
CvMat* cvCloneMat(const cvMat* mat);
//Free the matrix“mat”,both header and data
void cvReleaseMat(CvMat** mat);
int cvGetElemType(const CvArr* arr);
返回数组里元素的类型(CV_8UC1…CV_64FC4)
int cvGetDims( const CvArr* arr, int* sizes=NULL );
返回维数
int cvGetDimSize( const CvArr* arr, int index );
返回矩阵在该维数上矩阵的大小
矩阵数据的存储
方法一:利用宏CV_MAT_ELEM(),该宏传入矩阵、待提取的元素的类型、行和列数4个参数,返回提取出的元素的值
例:
CvMat* mat = cvCreateMat(5,5,CV_32FC1);
float element_3_2 = CV_MAT_ELEM(*mat,float,3,2);
利用宏CV_MAT_ELEM_PTR(),该宏传入矩阵、待提取的元素的行和列号,返回指向这个元素的指针。
例:
CvMat* mat = cvCreateMat(5,5,CV_32FC1);
float element_3_2 = 7.7;
*((float*)CV_MAT_ELEM_PTR(*mat,3,2))=element_3_2;//取出3行2列的元素并赋值,注意类型转换。
这些宏在每次调用的时候都要重新计算指针。在计划顺序访问矩阵中的所有元素时该方法效率明显不高;而且该方法仅适用于一维和二维数组。
方法二:
cvPtr*D家族cvPtr1D(),cvPtr2D(),cvPtr3D()和cvPtrND()
访问N维
可以用这些指针函数访问矩阵中的特定点,然后由这个点出发,用指针的算术运算得到指向矩阵中的其他数据的指针
注意:(1)多通道矩阵要考虑偏移量。如果是指向下一个通道指针加1即可,如果是指向下一个像素,要增加相应的偏移量,使其与通道数相等(2)矩阵数组的step元素:step是矩阵中行的长度,单位为字节。矩阵和图像的内存分配都是4字节的整数倍。所以三个字节宽度的矩阵被分配4个字节,最后一个字节被忽略。因此,如果我们得到一个字节指针,该指针指向数据元素,可以用step和这个指针相加即得这个点的下一行元素。如果是整型或浮点型矩阵,用step/4与指针相加来移到下一行,如果是双精度就是step/8。
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 );
参数说明:
int idx0,idx1,idx2:表示索引的整数值
int* type=NULL:表示输出值类型,可选
uchar* cvPtrND( const CvArr* arr, const int* idx, int* type=NULL, int
create_node=1, unsigned* precalc_hashval=NULL );
参数说明:
const int* idx:指向一个整型数组的指针,这个数组表示索引
cvGet*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, const 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, int idx2 );
double cvGetRealND( const CvArr* arr, const int* idx );
说明:
仅仅是用于读取数据,返回的是矩阵数据的实际值
用cvSet*D家族和cvSetReal*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, const int* idx, CvScalar value );
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, const int* idx, double value );
方法三:用自己的循环
//累加一个三通道矩阵中的所有元素
float sum(const CvMat* mat)
{
float s=0.0f;
for(int row=0;row<mat->rows;row++)
{
const float* ptr = (const float*)(mat->data.ptr + row*mat->step);
for(col=0;col<mat->cols;col++)
{
s += *ptr++;
}
}
return(s);
}
注意
矩阵元素data是一个联合体,用data.ptr来获得正确的指针
为使指针产生正确的偏移,必须用矩阵的行数据长度step
点的数组