一.基本數據類型:
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