zoukankan      html  css  js  c++  java
  • 《学习opencv》笔记——基本数据结构,CvMat,矩阵訪问

        老板让让做一个东东。输入端要用到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
    ",s);
    	getchar();
    	return 0;
    }
       to be continued


  • 相关阅读:
    关于虚函数那点破事
    两个分析HTML网页的方法
    C#实现web信息自动抓取
    ASP:打造内容管理系统之模板技术乱谈
    猪的FLASH-大肚腩
    猪的FLASH-深呼吸
    ASP.NET正则对象初看。
    今天搜索了一下堕落的卖猪贩一词。
    个人形象Show-卡通图
    检测远程URL是否存在的三种方法
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10832989.html
Copyright © 2011-2022 走看看