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

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

点的数组

你可能感兴趣的:(OpenCV学习笔记 -- 基本数据类型)