Opencv之Mat类

来源:互联网 发布:蜗牛辅助工具淘宝v1.8 编辑:程序博客网 时间:2024/05/18 03:43

  一、初识Mat类    

    Mat是OpenCV最基本的数据结构,Mat即矩阵(Matrix)的缩写,Mat数据结构主要包含2部分:Header和Pointer。Header中主要包含矩阵的大小,存储方式,存储地址等信息;Pointer中存储指向像素值的指针。我们在读取图片的时候就是将图片定义为Mat类型,其重载的构造函数一大堆,

 

     而矩阵又是图像的基本数据结构,我们做的所有动作几乎都是在矩阵的基础之上完成的。比如Mat img;有时,我们又需要详细地定义出矩阵的维度以及长、宽、数据类型等信息:Matimg(width,height,CV_8U);这就直接导致了Mat类一个庞大的构造函数群,如下所示:

 Mat::Mat()

 Mat::Mat(int rows, int cols, int type)

 Mat::Mat(Size size, int type)

 .....

 Mat::Mat(int ndims, const int* sizes, inttype, void* data, const size_t* steps=0)

 Mat::Mat(const Mat& m, const Range*ranges)

二、深入结构

       进一步数据,图像基本结构是二维的,3D图像还会是三维的,彩色图像还有多个channel(通道),而数据在内存中是一维存储的,;为了便于编程使用,opencv对一维数据进行矩阵的抽象封装,这个就是Mat类;Mat是一个基础类,封装了构造函数,重载运算符和基础的运算函数(很多类似于matlab的函数)。比如存一张10*10像素的单通道float图像,图像数据总共10*10*4*1字节,data指向第一个字节;Mat本身还有一个成员 int type;这个就是来记录Mat的数据类型;什么CV_32F等

 

       现在看看具体mat矩阵类中怎么用信息头和矩阵?

       用法一、赋值运算符和拷贝构造函数( ctor )只拷贝信息头,让每个 Mat 对象有自己的信息头,但共享同一个矩阵。

Mat A, C;                                 // 只创建信息头部分

A = imread(argv[1], CV_LOAD_IMAGE_COLOR);// 这里为矩阵开辟内存

 

Mat B(A);                                 // 使用拷贝构造函数

 

C = A;                                    // 赋值运算符

 

Mat D (A, Rect(10, 10, 100, 100) ); //using a rectangle

Mat E = A(Range:all(), Range(1,3)); //using row and column boundaries

    用法二、使用函数 clone() 或者copyTo() 来拷贝一副图像的矩阵,拷贝矩阵本身(不只是信息头和矩阵指针)

Mat F = A.clone();

Mat G;

A.   copyTo(G);

三、mat类的七种方法略


下面会给出链接,想看的可以点击链接

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/core/mat%20-%20the%20basic%20image%20container/mat%20-%20the%20basic%20image%20container.html

1)     使用Mat()构造函数

2)     在c/c++中通过构造函数进行初始化

3)     用已经存在的IplImage指针创建信息头

4)     利用Create()函数

5)     采用matlab式的初始化方式

6)     对小矩阵使用逗号分隔式初始化函数

7)     用已存在的对象创建新信息头clone()或copyTo()

 

注意:流操作符<<对于Mat的操作,仅限于Mat是2维的情况

 

     唯一要说的感觉是 CV_(S|U|F)C<通道数>,例如,数据类型可能是CV32FC1,即32bit的浮点数,或CV_8UC3,8bit的无符号整数,或CV_8UC3,无符号8bit整数,3通道,等等

Mat_<uchar>对应的是CV_8U,

 

Mat_<char>对应的是CV_8S,

 

Mat_<int>对应的是CV_32S,

 

Mat_<float>对应的是CV_32F,

 

Mat_<double>对应的是CV_64F

 

    CV_8UC3 意味着我们使用那些长的8 位无符号的 char 类型和每个像素都有三个项目的这三个通道的形成。这是预定义的四个通道数字。Scalar 是四个元素短向量。

 

还有就是CV_32F和CV_32F


看CV_32FC1和CV_64FC1的名字就知道,前者是32位数据,后者是64位数据。因此前者类型的数据必须以指向32位数据类型的指针存取,否则会报错,而后者类型的数据必须以指向64位数据类型的指针存取,否则会报错。

也就是说,你如果用cv_32fc1,那么后面对该矩阵的输入输出的数据指针类型都应该是float,这在32位编译器上是32位浮点数,也就是单精度。

你如果用cv_64fc1,那么后面对该矩阵的输入输出的数据指针类型都应该是double,这在32位编译器上是64位浮点数,也就是双精度。

 

看一个代码,略微感受一下Mat

typedef struct CVMat

{

   int type;

int step;

 

   int* refcount;

   int hdr_refcount;

   union

    {

       uchar* ptr;

       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;


 Scalar的解释

Mat M(7,7,CV_32FC2,Scalar(1,3));

解释如下:创建一个M矩阵,7行7列,类型为CV_32F,C2表示有2个通道。Scalar(1,3)是对矩阵进行初始化赋值。第一个通道全为1,第2个通道全为3,如果是CV_32FC3第一个通道全为1,第2个通道全为3,第三通道是0,如果是CV_32FC1,只显示第一通道为1

 

Mat L(3,sz, CV_8UC(1), Scalar::all(0));

初始化全部为0


5 0
原创粉丝点击