IplImage,CvMat ,Mat关系与转换


项目需要,最近在IplImage,CvMat ,Mat,CvArr之间转来转去;网上资料很多,版本有点混乱,整理一下,资源共享。

派生关系:CvArr -> CvMat -> IplImage 

IpImage 和CvMat  是C语言的struct。而cv::Mat 是c++中的结构。

现在的OpenCV要向Matlab靠拢,比如Mat常用函数imshow、imread、imwrite等和Matlab中函数一致;Mat类型侧重于计算,数学性较高,于是OpenCV对Mat类型的计算进行了优化,帮助管理内存分配,这样就不用自己create和release了,比使用CvMat 要方便。

而CvMat和IplImage类型更侧重于"图像"操作,CvArr及其子类常用函数比如cvLoadImage(),cvShowImage()等,和Mat常用函数不同。

 

1.1IplImage转CvMat

//opencv3.x版本:

//cvGetMat函数,深拷贝

IplImage* img;

CvMat temp;

CvMat* mat = cvGetMat(img, &temp);     

//cvConvert函数,深拷贝

CvMat *mat = cvCreateMat(img->height,img->width, CV_64FC3);      

cvConvert(img, mat);     

 

1.2CvMat转IplImage

//cvGetImage函数,深拷贝

CvMat M;

IplImage* img =cvCreateImageHeader(M.size(), M.depth(), M.channels());

cvGetImage(&M, img);   

// cvConvert函数,深拷贝

CvMat M;

IplImage* img = cvCreateImage(M.size(),M.depth(), M.channels());

cvConvert(&M, img);     

 

2.1IplImage转Mat

//opencv2.x版本:

//使用Mat的构造函数,默认情况下copyData为false

Mat::Mat(const IplImage* img, boolcopyData=false);

//当参数copyData为true时,则为深拷贝(复制整个图像数据)

Mat M(srcImg, true);

 

IplImage* srcImg;

//以下三种效果一致,均为浅拷贝

Mat M(srcImg);

Mat M(srcImg, false);

Mat M = srcImg;

 

//opencv3.x版本:

Mat m(src); //不复制内容

IplImage* srcImg;

Mat m = cvarrToMat(srcImg,true);

 

2.2Mat转IplImage

//低版本

Mat img;

IplImage *src;

src=&IplImage(img);

 

Mat m;

IplImage* dstImg = cvCloneImage(&(IplImage)m);

 

//浅拷贝

Mat M;

IplImage img = M;

IplImage img = IplImage(M);

 

3.1CvMat转Mat

//opencv2.x版本:

//使用Mat的构造函数,默认copyData为false

Mat::Mat(const CvMat* m, boolcopyData=false); 

//当参数copyData为true时,则为深拷贝

Mat b = Mat(a, true);

 

CvMat* a;

//以下三种效果一致,均为浅拷贝

Mat b(a);

Mat b(a, false);  

Mat b = a;

 

3.2Mat转CvMat

//浅拷贝

Mat a;

CvMat b = a;

//深拷贝

Mat a;

CvMat *b;

CvMat temp = a;    

cvCopy(&temp, b);  

 

4.(多通道)Mat, IplImage, CvMat的元素获取

 IplImage:

//i is the index of rows

//j is the index of cols

//c is the index of channel

((uchar*)pImg->imageData+i*pImg->widthStep)[j*3+c]

CV_IMAGE_ELEM(pImg,uchar,i,3*j+c)

 

CvMat:

CV_MAT_ELEM(cvmat,uchar,i,3*j+c) ;

 

Mat:

Mat m;

int h = m.rows; int w = m.cols;

int nc = m.channels();     

for (int i = 0;i<h;i++)

{

       for(intj = 0;j<w;j++)

       {

              Vec3b&elem = m.at<Vec3b>(i,j);

              for(int c = 0; c<nc; c++)

              {

                     ucharuc = elem[c] ;//Mat(i,j) of channel c

              }

       }

}

 

5.一些区别:

1.Mat类型是自动内存管理,不需要显式释放;而CvMat则需要调用cvReleaseMat(&cvmat)来释放,IplImage需要调用cvReleaseImage(&iplimage)来释放。
2.建立IplImage图像时,CvSize第一个参数为宽度,即列数;第二个参数为高度,即行数:IplImage*cvCreateImage(CvSize size, int depth, int channels );
CvSize cvSize( int width, int height );

3.建立CvMat矩阵时,第一个参数为行数,第二个参数为列数:
CvMat* cvCreateMat( int rows, int cols, int type );
4.IplImage内部buffer每行是按4字节对齐的,CvMat没有这个限制。

 

 

参考:

Mat, IplImage, CvMat, Cvarr关系及元素获取

http://blog.csdn.net/abcjennifer/article/details/17640195

OpenCV中矩阵类详解之三:CvMat,Mat和IplImage之间的转化和拷贝

http://blog.csdn.net/holybin/article/details/17711013

IpImage 与 cvImage, cvMat 与 cv::Mat

http://blog.sina.com.cn/s/blog_79bb01d00101ao59.html

OpenCV 2.4.3 Cheat Sheet学习(一)

http://blog.sina.com.cn/s/blog_8924265b0101fblj.html

猜你喜欢

转载自blog.csdn.net/qingyanyichen/article/details/51941925