老板让让做一个东东。输入端要用到opencv顺便就来学习一下。买了本书《学习opencv》翻来一看。opencv1.0,去官网上一看,opencv2.49。瞬间有种蛋碎的赶脚。看着第二章介绍一个头文件,在opencv2.49以下招了半天都没找到。。。泪奔~~

    只是看到一些论坛上说,这本书里还是讲了一些实用的算法的,所以还是决心细致读一读,里面的測试程序基本是亲手输入执行成功的,非常多样例我自也用不同的方法实现了一下。毕竟入门级新手。

望各位老鸟勿喷。还请各位大手多多指点。

        

1.opencv基本数据结构:




结构



成员



意义



CvPoint



int x,y



图像中的点



CvPoint2D32f     



float x,y



二维空间中的点



CvPoint3D32f



float x,y,z



三维空间中的点



CvSize 



int width,height



图像的尺寸



CvRect



int x,y,width,height



图像的部分区域



CvScalar



double val[4]



RGBA值



2.CvMat矩阵结构:

(1)两点注意:

1.在Opencv中没有向量结构,不论什么时候须要向量。都仅仅是一个列矩阵。

2.Opencv矩阵的概念与我们在线性代数课上学习过的概念相比。更抽象,特别是矩阵的元素。

(2)CvMat结构:

typedef struct CvMat{
  int type;
  int step;
  int* refcount;
  union{
  uchar* ptr;
  short* s;
  int* i;
  float *f1;
  double* db;
  } data;
union{
  int rows;
  int height;
  };
union{
  int cols;
  int width;
  };
}CvMat;


(3)矩阵的创建与释放

CvMat* cvCreateMat( int rows, int cols, int type );  //创建一个矩阵

CvMat* cvCreateMatHeader( int rows, int cols, int type ); //创建一个矩阵结构,不分配空间

CvMat* cvInitMatHeader(CvMat* mat,int rows,int cols,int type,void* data = NULL,int step = CV_AUTOSTEP);//用一个现有矩阵初始化矩阵

CvMat cvMat(int rows,int cols,int type,void* data = NULL);//初始化矩阵结构,不分配空间

CvMat* cvCloneMat( const cvMat* mat );//复制一个mat副本

void cvReleaseMat( CvMat** mat ); //释放矩阵


(4)创建一个矩阵程序:


#include <cv.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
float vals[] = {1,2,3,4};

CvMat rotmat;

cvInitMatHeader(
&rotmat,
2,
2,
CV_32FC1,
vals
);
cout << rotmat.cols <<endl;
cout << rotmat.step <<endl;
cout << rotmat.rows <<endl;
cout << rotmat.type <<endl;
getchar();
return 0;
}


3.矩阵数据的存取(简单的方法,麻烦的方法,恰当的方法)


(1)简单的方法:

利用CV_MAT_ELEM()宏存取矩阵


#include "stdafx.h"
#include <cv.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
float vals[] = {1,2,3,4};

CvMat* rotmat = cvCreateMat( 2, 2, CV_32FC1 );

cvInitMatHeader(
rotmat,
2,
2,
CV_32FC1,
vals
);
float ele = CV_MAT_ELEM(*rotmat,float,1,1);
cout << ele << endl;
getchar();
return 0;
}


另外宏CV_MAT_ELEM_PTR()须要三个參数,传入矩阵,待返回元素的行和列。

它和上个宏一样,仅仅只是返回的是指向元素的指针。须要自己固定类型。

(2)麻烦的方法

使用cvPtr*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
);


訪问实例:


#include <cv.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
float vals[] = {1,2,3,4};

CvMat* rotmat = cvCreateMat( 2, 2, CV_32FC1 );

cvInitMatHeader(
rotmat,
2,
2,
CV_32FC1,
vals
);
float *p = (float*) cvPtr2D(rotmat,1,1);
cout <<*p<<endl;
getchar();
return 0;
}


(3)恰当的方法

计算机视觉是一种密集型的任务,所以应该利用最有效的方法做事。

方法:


#include <cv.h>
#include <iostream>
using namespace std;

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(2,2,CV_32FC1);
float elem = 2;
*((float*)CV_MAT_ELEM_PTR( *mat, 0,0) ) = elem;
cvmSet(mat,0,1,3);
cvSetReal2D(mat,1,0,4);
cvSetReal2D(mat,1,1,5);
float s = sum(mat);
printf("%f\n",s);
getchar();
return 0;
}

   to be continued