[OpenCV] Basic data types - Matrix
Ref: http://docs.opencv.org/2.4.13/
基础数据结构
一、基本几何
-
矩形
"modules/core/src/drawing.cpp"
CV_IMPL void cvRectangle( CvArr* _img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness, int line_type, int shift ) { cv::Mat img = cv::cvarrToMat(_img); cv::rectangle( img, pt1, pt2, color, thickness, line_type, shift ); }
-
点
"modules/core/include/opencv2/core/types_c.h"
typedef struct CvPoint { int x; int y; } CvPoint;
typedef struct CvPoint3D64f { double x; double y; double z; } CvPoint3D64f;
-
面积
typedef struct CvSize { int width; int height; } CvSize;
-
大数表示 (例如:表示颜色)
typedef struct CvScalar { double val[4]; } CvScalar;
二、矩阵描述
- Mat
Ref: opencv基础知识------IplImage, CvMat, Mat 的关系和相互转换
在openCV中,Mat类型与CvMat和IplImage类型都可以代表和显示图像,
但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。
而CvMat和IplImage类型更侧重于“图像”,openCV对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。
补充:
IplImage由CvMat派生,而CvMat由CvArr派生即CvArr -> CvMat -> IplImage
CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat处理。
三、图片描述
- IplImage
"modules/core/include/opencv2/core/types_c.h"
typedef struct _IplImage { int nSize; /* sizeof(IplImage) */ int ID; /* version (=0)*/ int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */ int alphaChannel; /* Ignored by OpenCV */ int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */ char colorModel[4]; /* Ignored by OpenCV */ char channelSeq[4]; /* ditto */ int dataOrder; /* 0 - interleaved color channels 隔行扫描, 1 - separate color channels . cvCreateImage can only create images */ int origin; /* 0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style). */ int align; /* Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead. */ int width; /* Image width in pixels. */ int height; /* Image height in pixels. */ struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */ struct _IplImage *maskROI; /* Must be NULL. */ void *imageId; /* " " */ struct _IplTileInfo *tileInfo; /* " " */ int imageSize; /* Image data size in bytes (==image->height*image->widthStep in case of interleaved data)*/ char *imageData; /* Pointer to aligned image data. */ int widthStep; /* Size of aligned image row in bytes. */ int BorderMode[4]; /* Ignored by OpenCV. */ int BorderConst[4]; /* Ditto. */ char *imageDataOrigin; /* Pointer to very origin of image data (not necessarily aligned) - needed for correct deallocation */ } IplImage;
- CvMat
"modules/core/include/opencv2/core/types_c.h" 708L, 58287C
typedef struct CvMat { int type; int step; /* for internal use only */ int* refcount; int hdr_refcount; union { uchar*; 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] 初始化一个矩阵
#include "cv.h" #include <stdio.h> int main() { // Create an OpenCV Matrix containing some fixed data. // float vals[] = { 0.866025, -0.500000, 0.500000, 0.866025}; CvMat rotmat; cvInitMatHeader(&rotmat, 2, 2, CV_32FC1, vals);
printf("Ex 3_3 matrix initialized\n"); }
[2] 相关源代码:"modules/core/src/array.cpp"
[3] 初始化细节:Init Matrax ( ):
CV_IMPL CvMat* cvInitMatHeader( CvMat* arr, int rows, int cols, int type, void* data, int step ) { if( !arr ) CV_Error( CV_StsNullPtr, "" ); if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX ) CV_Error( CV_BadNumChannels, "" ); if( rows < 0 || cols <= 0 ) CV_Error( CV_StsBadSize, "Non-positive cols or rows" ); type = CV_MAT_TYPE( type ); arr->type = type | CV_MAT_MAGIC_VAL; arr->rows = rows; arr->cols = cols; arr->data.ptr = (uchar*)data; arr->refcount = 0; arr->hdr_refcount = 0; int pix_size = CV_ELEM_SIZE(type); int min_step = arr->cols*pix_size; if( step != CV_AUTOSTEP && step != 0 ) { if( step < min_step ) CV_Error( CV_BadStep, "" ); arr->step = step; } else { arr->step = min_step; } arr->type = CV_MAT_MAGIC_VAL | type | (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0); icvCheckHuge( arr ); return arr; }
[4] 其他相关API:Relevant Functions
// Create a new rows by cols matrix of type ‘type’. // CvMat* cvCreateMat( int rows, int cols, int type );
// Create only matrix 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 );
四、存取像素点
- 宏方法
"modules/core/include/opencv2/core/types_c.h"
#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \ (assert( (unsigned)(row) < (unsigned)(mat).rows && \ (unsigned)(col) < (unsigned)(mat).cols ), \ (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col)) #define CV_MAT_ELEM_PTR( mat, row, col ) \ CV_MAT_ELEM_PTR_FAST( mat, row, col, CV_ELEM_SIZE((mat).type) ) #define CV_MAT_ELEM( mat, elemtype, row, col ) \ (*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype)))
宏取值,简单但通用性不强:
#include "cv.h" #include <stdio.h> int main() { CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
// 1. 指针法 float element_3_2 = 7.7; *( (float*)CV_MAT_ELEM_PTR( *mat, 3, 2 ) ) = element_3_2;
// 2. 处理“浮点型,单通道矩阵” cvmSet( mat, 2, 2, 0.5000 );
// 3. 较常用 cvSetReal2D( mat, 3, 3, 0.3300 ); printf("Exercise 3_5, matrix created and accessed [3,2]=%f, [2,2]=%f, [3,3]=%f\n",
CV_MAT_ELEM( *mat, float, 3, 2 ),
CV_MAT_ELEM( *mat, float, 2, 2 ),
CV_MAT_ELEM( *mat, float, 3, 3 ) ); }
- Get pixel
"modules/core/src/array.cpp"
// CvMat and IplImage element functions 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, int* idx );
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, int* idx );
返回值类型占用空间大,也有小的方案 as following:
// Pointer access to matrix structures 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 );
uchar* cvPtrND( const CvArr* arr, int* idx, int* type = NULL, int create_node = 1, unsigned* precalc_hashval = NULL );
- Set Pixel
// Set element functions for CvMat or IplImage. 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, int* idx, double value );
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, int* idx, CvScalar value );
- 综合性例子
/* License: Oct. 3, 2008 Right to use this code in any way you want without warrenty, support or any guarentee of it working. BOOK: It would be nice if you cited it: Learning OpenCV: Computer Vision with the OpenCV Library by Gary Bradski and Adrian Kaehler Published by O'Reilly Media, October 3, 2008 AVAILABLE AT: http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134 Or: http://oreilly.com/catalog/9780596516130/ ISBN-10: 0596516134 or: ISBN-13: 978-0596516130 OTHER OPENCV SITES: * The source code is on sourceforge at: http://sourceforge.net/projects/opencvlibrary/ * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back): http://opencvlibrary.sourceforge.net/ * An active user group is at: http://tech.groups.yahoo.com/group/OpenCV/ * The minutes of weekly OpenCV development meetings are at: http://pr.willowgarage.com/wiki/OpenCV */ #include <stdio.h> #include <cv.h> #include <highgui.h> float sum( CvMat* mat ) { float s = 0.0f; for( int row=0; row<mat->height; row++ ) { float* ptr = mat->data.fl + row * mat->step/4; for( int col=0; col<mat->width; col++ ) { s += *ptr++; } } return( s ); }; int main(int argc, char** argv) { CvMat *mat = cvCreateMat(5,5,CV_32FC1); float element_3_2 = 7.7; *((float*)CV_MAT_ELEM_PTR( *mat, 3,2) ) = element_3_2; cvmSet(mat,4,4,0.5000); cvSetReal2D(mat,3,3,0.5000); float s = sum(mat); printf("%f\n",s); return 0; }