OpenCV图像类型介绍及其转换方式
Mat侧重于计算, OpenCV对Mat类型计算进行了优化.
CvMat / IplImage侧重于图像, OpenCV对图像操作(缩放/单通道提取/图像阈值操作等)进行了优化.
1. Mat
1.1 基本介绍
Mat基于C++的接口, 相比于IplImage它**不需要手动开辟空间和释放.**大多数OpenCV函数仍会手动开辟空间, 当传递已经存在的Mat对象时, 开辟好的矩阵空间会被重用.
Mat主要分两部分, 一部分是矩阵头(矩阵尺寸、存储方法、存储地址信息), 另一部分是指向存储所有像素的矩阵指针. Mat使用ARC内存管理机制, 每个Mat对象有自己的信息头, 但共享一个矩阵.
- 而拷贝构造函数则只拷贝信息头和矩阵指针, 而不拷贝矩阵.
 
拷贝一个Mat对象需要用到 clone() 或 copyTo():
1  | ...  | 
1.2 显式地创建一个Mat对象
首先介绍一下常用的宏CV_8UC3, 类似的还有:
1  | 
对于二维多通道图像,首先要定义其尺寸,即行数和列数。
然后,需要指定存储元素的数据类型以及每个矩阵点的通道数。为此,依据下面的规则有多种定义
CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]
比如 CV_8UC3 表示使用8位的 unsigned char 型,每个像素由三个元素组成三通道。预先定义的通道数可以多达四个。 Scalar 是个short型vector。指定这个能够使用指定的定制化值来初始化矩阵。当然,如果你需要更多通道数,你可以使用大写的宏并把通道数放在小括号中,如下所示:
1  | int sz[3] = {2,2,2};  | 
1.Mat()构造函数
1  | Mat M(2,2, CV_8UC3, Scalar(0,0,255));  | 

2.使用mtx()函数为已存在IplImage创建信息头
1  | IplImage* img = cvLoadImage("greatwave.png", 1);  | 
3.使用Create()函数
这个方法不能为矩阵设置初始值, 它只是在改变尺寸时重新为矩阵数据开辟内存
1  | M.create(4,4, CV_8UC(2));  | 

4.MATLAB形式的初始化方式: zeros(), ones(), :eyes() 。使用以下方式指定尺寸和数据类型
1  | Mat E = Mat::eye(4, 4, CV_64F);  | 

5.对于小矩阵你可以用逗号分隔的初始化函数
1  | Mat RowClone = C.row(1).clone();  | 

6.使用 clone() 或者 copyTo() 为一个存在的 Mat 对象创建一个新的信息头
1  | Mat RowClone = C.row(1).clone();  | 

1.3 格式化打印
调用函数 randu() 来对一个矩阵使用随机数填充,需要指定随机数的上界和下界:
1  | Mat R = Mat(3, 2, CV_8UC3);  | 
1.**默认方式:**cout << R

2.**Python:**cout << format(R,“python”)

3.**CSV:**cout << format(R, “csv”)

4.**Numpy:**cout << format(R, “numpy”)

5.**C语言:**cout << format(R, “C”)

CvMat
官网介绍说CvMat已经被淘汰, 建议使用Mat替代
IplImage
IplImage全称是Intel Procesing Library Image, 顾名思义, 是Intel系统原生格式.
OpenCV可能只支持IplImage的子集.
几种格式之间的转换
1.Mat -> IplImage
1  | IplImage pImg= IplImage(imgMat);  | 
2.Mat -> CvMat
1  | CvMat cvMat = imgMat;  | 
3.IplImage -> Mat
1  | IplImage* img = cvLoadImage("greatwave.png", 1);  | 
4.IplImage -> CvMat
1  | CvMat cvMat = cvGetImage(matI,img);  | 
5.CvMat -> Mat
1  | Mat::Mat(const CvMat* m, bool copyData=false); // 可以选择是否复制数据  | 
6.CvMat -> IplImage
1  | // Mathod 1:  | 
7.IplImage * -> Byte *
1  | BYTE *data = img->imageData;  | 
8.BYTE * -> IplImage *
1  | IplImage *img = cvCreateImageHeader(cvSize(width,height), depth, channels);  |