CvMat, Mat和IplImage之间的转化和拷贝

在OpenCV中Mat、CvMat和IplImage类型都可以代表和显示图像。IplImage由CvMat派生,而CvMat由CvArr派生即CvArr -> CvMat -> IplImage,Mat类型则是C++版本的矩阵类型(CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat处理)。
其中Mat类型侧重于计算,数学性较高,OpenCV对Mat类型的计算也进行了优化;而CvMat和IplImage类型更侧重于"图像",OpenCV对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。很多时候需要三种类型的相互转化,这里简要介绍一下。

CvMat和Mat间的转化和拷贝
1、CvMat之间的复制

//注意:深拷贝 - 单独分配空间,两者相互独立  
CvMat* a;  
CvMat* b = cvCloneMat(a);   //copy a to b  

2、Mat之间的复制

// 注意:浅拷贝 -  不复制数据只创建矩阵头,
// 数据共享(更改a,b,c的任意一个都会对另外2个产生同样的作用)  
Mat a;  
Mat b = a; //a "copy" to b  
Mat c(a); //a "copy" to c  

//注意:深拷贝  
Mat a;  
Mat b = a.clone(); //a copy to b  
Mat c;  
a.copyTo(c); //a copy to c  

3、CvMat转Matb

// 使用Mat的构造函数:Mat::Mat(const CvMat* m, bool copyData=false);
// 默认情况下copyData为false  
CvMat* a;  
// 注意:以下三种效果一致,均为浅拷贝  
Mat b(a);   //a "copy" to b  
Mat b(a, false);    //a "copy" to b  
Mat b = a;  //a "copy" to b  

//注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据)  
Mat b = Mat(a, true); //a copy to b  

4、Mat转CvMat

//注意:浅拷贝  
Mat a;  
CvMat b = a; //a "copy" to b  
  
//注意:深拷贝  
Mat a;  
CvMat *b;  
CvMat temp = a; //转化为CvMat类型,而不是复制数据  
cvCopy(&temp, b); //真正复制数据  

IplImage与上述二者间的转化和拷贝
1、IplImage之间的复制
这个不赘述了,就是cvCopy与cvCloneImage使用区别,贴张网上的图:
这里写图片描述
2、IplImage转Mat

// 使用Mat的构造函数:Mat::Mat(const IplImage* img, bool copyData=false);    
// 默认情况下copyData为false  
IplImage* srcImg = cvLoadImage("Lena.jpg");  
//注意:以下三种效果一致,均为浅拷贝  
Mat M(srcImg);  
Mat M(srcImg, false);  
Mat M = srcImg;  
  
//注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据)  
Mat M(srcImg, true);  

但是在opencv3.0 下上面的代码在编译的时候会出现错误。
应该修改为:

cv::Mat mat = cv::cvarrToMat(img); 

3、Mat转IplImage

//注意:浅拷贝 - 同样只是创建图像头,而没有复制数据  
Mat M;  
IplImage img = M;  
IplImage img = IplImage(M);  

4、IplImage转CvMat

//法一:cvGetMat函数  
IplImage* img;  
CvMat temp;  
CvMat* mat = cvGetMat(img, &temp);  //深拷贝  
//法二:cvConvert函数  
CvMat *mat = cvCreateMat(img->height, img->width, CV_64FC3);  //注意height和width的顺序  
cvConvert(img, mat);    //深拷贝  

5、CvMat转IplImage

//法一:cvGetImage函数  
CvMat M;  
IplImage* img = cvCreateImageHeader(M.size(), M.depth(), M.channels());  
cvGetImage(&M, img);    //深拷贝:函数返回img  
//也可写成  
CvMat M;  
IplImage* img = cvGetImage(&M, cvCreateImageHeader(M.size(), M.depth(), M.channels()));  
//法二:cvConvert函数  
CvMat M;  
IplImage* img = cvCreateImage(M.size(), M.depth(), M.channels());  
cvConvert(&M, img); //深拷贝  

最后注意:

1 Mat类型是自动内存管理,不需要显式释放(当然也可以手动调用release()方法强制Mat矩阵数据释放);而CvMat则需要调用cvReleaseMat(&cvmat)来释放,IplImage需要调用cvReleaseImage(&iplimage)来释放。
2 建立CvMat矩阵时,第一个参数为行数,第二个参数为列数: CvMat* cvCreateMat( int rows, int
cols, int type );
3 建立IplImage图像时,CvSize第一个参数为宽度,即列数;第二个参数为高度,即行数:

IplImage* cvCreateImage(CvSize size, int depth, int channels );
CvSize cvSize( int width, int height );

4 IplImage内部buffer每行是按4字节对齐的,CvMat没有这个限制。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值