opencv从入门到精通(3)——基本数据类型

1.常用的结构

opencv中定义了一些实用的数据类型,如下:

    结构                                             成员变量                                表示的含义                   
  1. CvPoint                                       int x,y                                       图像中的点                   
  2. CvPoint2D32f                            float x,y                                   二维空间中的点           
  3. CvPoint3D32f                            float x,y,z                               三维空间中的点           
  4. CvSize                                         int width,height                 图像的尺寸                    
  5. CvRect                                        int x,y,width,height    图像的一个区域            
  6. CvScalar                                    double val[4]                         RGBA的值                        
上述结构的第一个的第一个字母小写就是相应的构造函数,由于是用C编写的故实际上是内联函数,比如之前常用的cvSize。通过这些函数就可以很方便的进行一些操作,比如:
#include 
#include 
#include  
#include   
#include   
#include "cv.h"  
#include "highgui.h"
   using namespace cv;
   using namespace std;	

int main( ) {
    cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );
	IplImage* img= cvCreateImage(cvSize( 200, 200 ),IPL_DEPTH_8U,3 );
	// cvRectangle矩形函数参数: 图片, 左上角, 右下角, 颜色, 线条粗细(取负值时函数绘制填充了色彩的矩形。), 线条类型,点类型
	cvRectangle(img,cvPoint(20,20),cvPoint(100,100),cvScalar(255,0,0),-1);
	//cvCircle圆形函数参数为:承载的图像、圆心、半径、颜色、粗细、线型  
	cvCircle(img,cvPoint(150,150),30,Scalar(0,0,0),1); 
	cvShowImage("Example1",img);
	cvWaitKey(0);
	cvReleaseImage( &img );
	cvDestroyWindow("Example1");
	return 0;
}
opencv从入门到精通(3)——基本数据类型_第1张图片

2.矩阵和图像类型

  1.CvMat矩阵“头”结构

opencv中没有向量结构,但可以用一列矩阵表示;矩阵中的元素也可以不是数字,而是其他类型。CvMat的头结构为:
typedef struct CvMat {
    int type;
    int step;
    int* refcount;     // for internal use only
    union {
         uchar* ptr;
         short* s;
         int*    i;
         float* fl;
         double* db;
    } data;
    union {
         int rows;
         int height;
    };
    union {
         int cols;
         int width;
    };
} CvMat;
可见里面包含矩阵的行数,列数,数据类型,行数据长度和一些指向数据的指针。
创建CvMat结构有多种方法。

         1.使用函数CvMat* cvCreateMat( int rows, int cols, int type )
 2.使用CvMat* cvCreateMatHeader( int rows, int cols, int type );创建CvMat结构但不分配内存。
3.CvMat* cvInitMatHeader(
    CvMat* mat,                                                                                                                         
   int   rows,
     int   cols,
   int   type,
   void* data = NULL,
  int   step = CV_AUTOSTEP);为一个已经存在的CvMat结构初始化
 4.CvMat cvMat(int   rows,int   cols,int   type,void* data = NULL);与cvInitMatHeader类似但分配内存
         5.CvMat* cvCloneMat( const cvMat* mat );依据一个现有矩阵创建新的矩阵
 6.void cvReleaseMat( CvMat** mat );清除矩阵
接下来举一个创建矩阵的例子,编译遇到符号冲突问题按Ctrl+F5运行。
#include 
#include 
#include  
#include   
#include   
#include "cv.h"  
    using namespace cv;
	using namespace std;	

int main()
{
  CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
 float vals[25];
 for(int i=0;i<25;i++)
 {
	 vals[i]=i;
 } 
  cvInitMatHeader(mat,5,5, CV_32FC1,vals);//用已有的数据Val初始化矩阵
  float element_3_2 = CV_MAT_ELEM( *mat, float, 3, 2 );//获取第3行第2列的元素
  printf("所创建矩阵的[3,2]=%f\n",element_3_2);
  return 0;
}

 之后就可进行简单的访问 
  
  1.   函数cvGetElemType(const CvArr* arr)返回整型常数表示结构
  2. cvGetDims(const CvArr* arr,int* sizes=NULL)返回维数
  3. cvGetDimSize(const CvArr* arr,int index)返回index所对应维的大小,对于二维矩阵,第0维表示宽度,第一维表示高。

3.获取矩阵中的数据

在多通道的矩阵中,通道是连续的,如3通道2维表示rgb图像的矩阵中,数据存储形式为rgbrgbrgb....,也就是说指针移动一位进入下一个通道;移动3位进入下一个像素。另外矩阵结构中的step元素表示矩阵行的长度,得到一个指向某点的字节指针,加上step后便到了该点的下一行;而整型和浮点型的矩阵加上step/4,双精度矩阵加上step/8到下一行。

 3.1cvPtr*D()函数族

  
 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
	);

3.2 自己计算矩阵的指针
这里要注意多通道矩阵的概念,也就是每个矩阵的元素不是一个点,而是一个c维点列,这就好比一个集合的元素也可以是一个集合。之前讲过多通道矩阵是顺序存储的。
对于一个宽为mat->width,高为mat->height的c通道矩阵,每行的字节长度为mat->step,矩阵头的指针为mat->data.fl,那么a行b列i通道变量的位置为mat->data.fl+a*mat->step/4+b*c+i。注意这里面每行的长度用mat->step计算,而不用mat->width*c,当矩阵不是逐行连续存储的时候这两个可能是不相等的,用后者时出错。下面举一个例子:
#include 
#include 
#include  
#include   
#include   
#include "cv.h"  
    using namespace cv;
	using namespace std;	



int main()
{
    CvMat *mat = cvCreateMat(5,5,CV_32FC3);//5*5的3通道矩阵
	//赋值
	for( int a=0; aheight; a++ ) {
		float* ptr = mat->data.fl + a * mat->step/4;
			for( int b=0; bwidth; b++ ) {
				for(int i=0;i<3;i++){
					*(mat->data.fl+a*mat->step/4+b*3+i)=a+b+i;
				}
					
		 }
    }
	//显示
    for( int a=0; aheight; a++ ) {
		printf("\n");
		float* ptr = mat->data.fl + a * mat->step/4;
			for( int b=0; bwidth*3; b++ ) {
				printf("%f ",*ptr);
				ptr++;
    }
  }
    return 0;
}






你可能感兴趣的:(计算机视觉,opencv,c语言,函数,数据,计算机视觉)