opencv中图像数据容器一般有Mat,cvMat和IplImage。我们在平常的代码中,由于不同的函数的参数类型不一致,经常需要转换这三者之间的相互转化。网上有大量的杂七杂八的资料,望结合实际而用之。
Mat是一个多维的密集数据数组,可以用来处理向量和矩阵、图像、直方图等等常见的多维数据,所以Mat侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。
而CvMat和IplImage类型更侧重于“图像”,opencv对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。
(1)将IplImage类型转换到Mat类型
Mat::Mat(const IplImage* img, bool copyData=false);默认情况下,新的Mat类型与原来的IplImage类型共享图像数据,转换只是创建一个Mat矩阵头。当将参数copyData设为true后,就会复制整个图像数据。
用代码可以验证何谓"共享图像数据"
#include <iostream> #include <highgui.h> using namespace std; using namespace cv; int main() { //IplImage->Mat IplImage *image = cvLoadImage("I:\\OpenCV Learning\\picture\\sumpalace.jpg"); //显示IplImage图像 cvShowImage("IplImage_image0",image); //转换容器类型,从IplImage->Mat Mat matImage = Mat(image,false); //显示Mat图像 imshow("Mat_image0",matImage); //更改mat图像的数据:在图像中画一个圆 circle(matImage,cvPoint(100,100),64,Scalar(0,0,255),1,1,1); //显示IplImage图像和Mat图像 cvShowImage("IplImage_image1",image); imshow("Mat_image1",matImage); waitKey(0); return 0; }观察结果:更改mat图像数据后,IplImage图像的数据也会更改,二者使用的数据是同一数据,此乃共享。
(2)将Mat类型转换到IplImage类型
Mat matImage; IplImage IplImage_image = matImage;同样是共享图像数据,只是创建了图像头,不复制数据。
(3)将CvMat类型转换为Mat类型
Mat::Mat(const CvMat* m, bool copyData=false);类似IplImage -> Mat,可选择是否复制数据
(4)将Mat类型转换为CvMat类型
Mat matImage; CvMat cvMatImage = matImage;
同样是共享图像数据,只是创建了图像头,不复制数据。