opencv学习笔记[9]:Opencv的基本数据类型和矩阵结构
一.基本数据类型:
1.CvPoint
图像中的点
Opevcv提供的数据类型中最简单的就是CvPoint.
typedef struct CvPoint { int x; int y; } CvPoint |
CvPoint包含int x 和int y两个数据成员,它的变体有CvPoint2D32f 和 CvPoint3D32f.
CvPoint2D32f包含float x , float y两个数据成员.
二维空间中的点
typedef struct CvPoint2D32f { float x; float y; } CvPoint2D32f |
CvPoint3D32f 包含float x , float y , float z 三个数据成员.
三维空间中的点
typedef struct CvPoint3D32f { float x; float y; float z; } CvPoint3D32f |
2. CvSize
CvSize的数据成员是: int width , int height.
图像的尺寸
typedef struct CvSize { int width; int height; } CvSize;
|
对应的浮点类型的数据成员 , CvSize的变体: CvSize2D32f.
typedef struct CvSize2D32f { float width; float height; } CvSize2D32f; |
3.CvRect
图像的部分区域
派生自CvPoint和CvSize.
typedef struct CvRect { int x; int y; int width; int height; } CvRect; |
4.CvScalar
RGBA值
有一个单独的数据成员val , 它是一个指向4个双精度浮点数数组的指针.
typedef struct CvScalar { double val[4]; } CvScalar
|
5.CvMat
typedef struct CvMat { int type; int step;
/* for internal use only */ int* refcount; int hdr_refcount;
union { uchar* ptr; short* s; int* i; float* fl; double* db; } data;
#ifdef __cplusplus union { int rows; int height; };
union { int cols; int width; }; #else int rows; int cols; #endif
} CvMat; |
二、矩阵的创建和释放:
1.矩阵的创建
Path1: CvMat* cvCreateMat(int rows, int cols, int type) //分配内存空间 Path2: CvMat* cvCreateMatHeader(int rows, int cols, int type) //不分配分配内存空间 Path3: CvMat* cvInitMatHeader(CvMat* mat, int rows, int cols, int type, void* data=NULL, int step=CV_AUTOSTEP)//利用现有的mat结构创建一个新的矩阵 Path4: CvMat cvMat(int rows, int cols, int type, void* data=NULL) //轻量级创建一个矩阵并分配存储空间的办法 Path5: CvMat* cvCloneMat(const CvMat* mat) //header and data are all allocated. |
#include <cv.h> #include <highgui.h> int main() { float vals[]={0.866025,-0.50000,0.500000,0.866025}; CvMat rotmat; cvInitMatHeader(&rotmat,2,2,CV_32FC1,vals); } |
2.矩阵的存取方法:
1.简单的方法: CV_MAT_ELEM() CV_MAT_ELEM_PTR() 存取数据。 例程: CvMat * mat1 = cvCreateMat( 5,5,CV_32FC1); float element_3_3 = 7.7; *((float *)CV_MAT_ELEM_PTR(*mat1,3,2) ) =element_3_3; 2.麻烦的方法: 返回指针的: C: uchar* cvPtr1D(const CvArr* arr, int idx0, int* type=NULL)
C: uchar* cvPtr2D(const CvArr* arr, int idx0, int idx1, int* type=NULL)
C: uchar* cvPtr3D(const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL)
C: uchar* cvPtrND(const CvArr* arr, int* idx, int* type=NULL, int createNode=1, unsigned int* precalcHashval=NULL)
返回元素对象: cvGetReal*D() cvGet*D() cvSetReal*D() cvSet*D() cvSet()//处理单通道数据 cvGet() //处理单通道数据 |
3.适当的方法 /** 累加一个三通道矩阵中的所有元素 **/ #include <cv.h> #include <highgui.h>
float sum(const CvMat * mat) { float s = 0.0f; for(int row=0;row<mat->rows;row++) { float * ptr = (float *)(mat->data.ptr + row * mat->step);//每一行都要重新计算起始位置 for(int col =0;col<mat->cols;col++) { s+= *ptr ++; //ptr++指向下一个数据 } } return s; } int main() { float vals[]={0.866025,-0. |
3.点的数组
注意点的存储和内存布局的关系。
例如:有n个三维的点,存储到CvMat 结构中,有几种存储方式?
①用一个二维数组,数组的类型是:CV32FC1,n行3列
②用一个二维数组,数据的类型是:CV32FC1,3行n列
③用一个二维数组,数据的类型是:CV32FC3,n行1列
④用一个二维数组,数据的类型是:CV32FC3,1行n列
注意:CV32FC1等的结构都是顺序型的通道。通道的概率其实我也不是很明确。
目前的理解是:
我们可以看出,前三种的内存分配情况相同,但最后一种的内存分配不同。更复杂的是,如果有n维数组,每个数组的元素是c维(c可能是 通道数)时。所以,多维数组(矩阵)和一个一维但包含多维数据的数组一般是不同的。
对于一个Rows行Cols列,通道数为Channels的矩阵,访问其中第row行,第col列,第channel通道的数据,可以使用如下公式:
数据地址偏移量=row*Cols*Channels+col*Channels+channel
posted on 2013-03-04 16:59 0fengfan0 阅读(2948) 评论(0) 编辑 收藏 举报