在OpenCV中,现在有很多种结构类型可以用来表示图像,它们之间有区别又有联系,现在记录一下它们之间的区别和相似之处,以便后面查看。
其中类型有:
1. Iplimage,2. Mat,3.CvMat, 4.CVArr;
其中:
1. IplImage:
较老版本的图像存储类型,在2.0之前使用;
2. CvArr:
也是较老的一种存储结构,是一种抽象的基类。
3. CvMat:
矩阵结构。
4. Mat:
新版本中使用的,推荐使用,是一个图像容器,基本上讲 Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。(参考某文库资料)。
============================
这些类型之间的相互转换:
1. IplImage--> Mat
函数原型:
Mat::Mat(const IplImage* img, bool copyData=false);
默认情况下,新的Mat类型与原来的IplImage类型共享图像数据,转换只是创建一个Mat矩阵头。当将参数copyData设为true后,就会复制整个图像数据。
例子:
IplImage*iplImg = cvLoadImage("a.jpg", 1);
Matmtx(iplImg); // IplImage* ->Mat 共享数据
// or : Mat mtx = iplImg;
2.Mat-->IplImage
同样只是创建图像头,而没有复制数据。
例:
IplImage pImg= IplImage(imgMat);
3. Mat-->CvMat
与IplImage的转换类似,不复制数据,只创建矩阵头。
例:
// 假设Mat类型的imgMat图像数据存在
CvMat cvMat = imgMat; // Mat -> CvMat
4. CvMat-->Mat
与IplImage的转换类似,可以选择是否复制数据。
Mat::Mat(const CvMat* m, bool copyData=false);
===========
总结:
1. Mat类型较CvMat和IplImage有更强的矩阵运算能力,支持常见的矩阵运算,所以将IplImage类型和CvMat类型转换为Mat类型更易于数据处理。 Mat类型可用于直接存储图像信息,通过函数imread、imwrite、imshow等实现,似乎在某种程度上可以取代IplImage类型。在计算密集型的应用当中,将CvMat与IplImage类型转化为Mat类型将大大减少计算时间花费。
2. 在openCV中,Mat类型与CvMat和IplImage类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。而CvMat和IplImage类型更侧重于“图像”,openCV对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。
IplImage由CvMat派生,而CvMat由CvArr派生即 CvArr -> CvMat -> IplImage
CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat处理