by 麦香鱼香麦
一、五个常见的数据类型:
1.CvPoint
CvPoint
二维坐标系下的点,类型为整型
CvPoint2D32f //二维空间中的点
CvPoint3D32f //三维空间中的点
typedef struct CvPoint { //默认左上为基点 int x; /* X坐标, 通常以0为基点 */ int y; /* y坐标, 通常以0为基点 */ } CvPoint; /* 构造函数 */ inline CvPoint cvPoint( int x, int y ); //内联函数,表示图像中的点坐标 /* 从 CvPoint2D32f类型转换得来 */ inline CvPoint cvPointFrom32f( CvPoint2D32f point )
CvSize
矩形框大小,以像素为精度
CvSize2D32f //浮点型
typedef struct CvSize
{
int width; /* 矩形宽 */
int height; /* 矩形高 */
}
CvSize;
/* 构造函数 */
inline CvSize cvSize( int width, int height );//返回图像的尺寸。
IplImage* img; img = cvLoadImage("D:\\PERSONAL\\VC++\\OpenCV\\image\\red.jpg"); cvNamedWindow("pikaqiu"); CvPoint pt1; pt1.x = 1; pt1.y = 1; CvPoint pt2; pt2.x = 100; pt2.y = 100; // CvRect rect; // cvRect(pt1.x,pt1.y,15,15); // CvScalar cvScalar( cvRectangle(img,pt1,pt2,CV_RGB(0,0,0)); cvShowImage("pikaqiu",img); cvWaitKey(0); cvReleaseImage(&img); cvDestroyWindow("pikaqiu");
3.CvRect
CvRect
矩形框的偏移和大小 可以用来表示图像的部分区域 具体用法待后续学习
typedef struct CvRect
{
int x; /* 方形的最左角的x-坐标 */
int y; /* 方形的最上或者最下角的y-坐标 */
int width; /* 宽 */
int height; /* 高 */
}
CvRect;
/* 构造函数*/
inline CvRect cvRect( int x, int y, int width, int height );
4.CvScalar
可以用来表示B、G、R和alpha(表示透明度)
CvScalar
可存放在1-,2-,3-,4-TUPLE类型的捆绑数据的容器
typedef struct CvScalar
{
double val[4]
}
CvScalar;
/* 构造函数1:用val0初始化val[0]用val1初始化val[1], 以此类推*/
inline CvScalar cvScalar( double val0, double val1=0,double val2=0, double val3=0 );
/* 构造函数2:用val0123初始化所有val[0]...val[3] */
inline CvScalar cvScalarAll( double val0123 );
/* 构造函数3:用val0初始化val[0],用0初始化val[1],val[2],val[3] */
inline CvScalar cvRealScalar( double val0 );
5.CvArr->CvMat->IplImage
使得接口函数更加通用。
by 麦香鱼香麦
二、矩阵元素的访问方式
方式一 :第一种是调用cvGetReal_1D/2D/3D……//一维二维三维矩阵
//========= 二维矩阵,单通道。
int _tmain(int argc, _TCHAR* argv[]) { float data[18]={ 1, 2,3,4,5,6, 7, 8,9,10,11,12, 13,14,14,16,17,18 }; CvMat mat; //初始化矩阵 cvInitMatHeader(&mat,3,6,CV_32FC1,data);//CV_32FC1:4字节,单通道。3行6列。 //方式一访问 通过cvGetReal for(int y = 0 ; y < mat.rows ; y++) { for(int x = 0 ; x < mat.cols ; x++ ) { float value = (float)cvGetReal2D(&mat,y,x);//二维的数组 注意是先 y 后 x printf("%f ",value); } printf("\n"); } return 0; }
//========= 二维矩阵,双通道每个元素中有两个值(X1,X2)
example1: 利用单通道显示 同样的显示效果
…… cvInitMatHeader(&mat,3,3,CV_32FC1,data);//CV_32FC1:4字节,单通道。3行6列。 …… for(int y = 0 ; y < mat.rows ; y++) { for(int x = 0 ; x < mat.cols ; x++ ) { float value[2]; value[0] = (float)cvGetReal2D(&mat,y,x); value[1] = (float)cvGetReal2D(&mat,y,++x); printf("(%f,%f) ",value[0],value[1]); } printf("\n"); }
注释
/* value = arr(idx0,idx1,...) */
CVAPI(CvScalar) cvGet1D( const CvArr* arr, int idx0 );
CVAPI(CvScalar) cvGet2D( const CvArr* arr, int idx0, int idx1 );
CVAPI(CvScalar) cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
CVAPI(CvScalar) cvGetND( const CvArr* arr, const int* idx );
/* for 1-channel arrays */
CVAPI(double) cvGetReal1D( const CvArr* arr, int idx0 );
CVAPI(double) cvGetReal2D( const CvArr* arr, int idx0, int idx1 );
CVAPI(double) cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );
CVAPI(double) cvGetRealND( const CvArr* arr, const int* idx );
example2: 利用双通道
注意cvInitMatHeader() 中的参数3,3(三行三列) 以及 CV_32F2 表示双通道
…… cvInitMatHeader(&mat,3,3,CV_32FC2,data);// CV_32FC1:4字节,双通道。3行3列。 …… for(int y = 0 ; y < mat.rows ; y++) { for(int x = 0 ; x < mat.cols ; x++ ) { CvScalar value = cvGet2D(&mat,y,x); printf("(%f,%f) ",value.val[0],value.val[1]); } printf("\n"); }
//多维度的 //int size[3]={2,2,2}; //x y z 三个坐标值的取值范围1/0 //CvMatND mat_nd; //cvInitMatNDHeader(&mat_nd,3,size,CV_32FC1,data);//3维 /CV_32FC1:4字节,单通道。
//======== 二维一通道(类似B)
CvMat mat; //方式二:通过指针访问 //初始化矩阵 cvInitMatHeader(&mat,3,6,CV_32FC1,data);//CV_32FC1:4字节,单通道。3行6列。 int nchannals = 1; //修改矩阵的通道值 //mat.data.ptr//数据块的起始地址 for(int y = 0 ; y < mat.rows ; y++) { float* p_float = (float*)(mat.data.ptr + y*mat.step); //ptr是 unsigened char* for(int x = 0 ; x < mat.cols ; x++ ) { float value = *(p_float + x*nchannals); printf("%f ",value); } printf("\n"); }修改矩阵的通道值时,要注意初始化函数 cvInitMatHeader() 中的一致。
指针的加加减减,改变的数据类型的字节数 2(char/unsigned char [sizeof(XXX)]) 4(int)
/======== 二维双通道(B,G)
CvMat mat; //方式二:通过指针访问 //初始化矩阵 cvInitMatHeader(&mat,3,3,CV_32FC2,data);//CV_32FC1:4字节,单通道。3行6列。 int nchannals = 2; //修改矩阵的通道值 //mat.data.ptr//数据块的起始地址 for(int y = 0 ; y < mat.rows ; y++) { 偏移到第 y 行 float* p_float = (float*)(mat.data.ptr + y*mat.step); //ptr是 unsigened char* for(int x = 0 ; x < mat.cols ; x++ ) { float value[2]; value[0] = *(p_float + x*nchannals); value[1] = *(p_float + x*nchannals + 1); printf("(%f,%f) ",value[0],value[1]); } printf("\n"); }
要注意指针偏移的位置,每步是单位的 sizeof(XXX) 。
在需要将矩阵当做形参传递到子程序中去时,最好使用指针。
by 麦香鱼香麦