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