您的位置:首页 > 运维架构

OpenCV学习笔记 -- 基本数据类型

2012-02-14 17:02 701 查看
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

点的数组
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: