opencv中Mat、CvMat和IplImage的相互转化
2015-12-05 20:07
399 查看
opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利Mat类型较CvMat和IplImage有更强的矩阵运算能力,支持常见的矩阵运算(参照Matlab中的各种矩阵运算),所以将IplImage类型和CvMat类型转换为Mat类型更易于数据处理。Mat类型可用于直接存储图像信息,通过函数imread、imwrite、imshow等实现(与Matlab中的函数相似),似乎在某种程度上可以取代IplImage类型。
1、四者关系:
1).CvMat(CvMat is now obsolete, consider using Mat instead)不建议用;
2). 派生关系:CvArr -> CvMat -> IplImage
3). Mat是C++接口,和IplImage有所不同。
2. 相互转换
1). Mat与IplImage相互转换
IplImage* src;
某文章说,转换应该是Mat m(src); 而这不会复制内容,真正能复制内容的是:
Mat -> IplImage:
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
Mat m;
IplImage* transIplimage = cvCloneImage(&(IplImage) m);
IplImage -> Mat
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
IplImage* transIplImage;
Mat m = cvarrToMat(transIplImage,true);
2). CvMat与IplImage相互转换
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
IplImage* transIplImage;
CvMat* cvmat;
cvGetMat(transIplImage,cvmat);
cvGetImage(cvmat,transIplImage);
3. (多通道)Mat, IplImage, CvMat的元素获取
单通道的网上很多,这里只写多通道:
1). IplImage
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//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)
2 ).Mat
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
Mat m;
int h = m.rows; int w = m.cols;
int nc = m.channels();
for (int i = 0;i<h;i++)
{
for(int j = 0;j<w;j++)
{
Vec3b& elem = m.at<Vec3b>(i,j);
for (int c = 0; c<nc; c++)
{
uchar uc = elem[c] ;//Mat(i,j) of channel c
}
}
}
3). CvMat
CV_MAT_ELEM(cvmat,uchar,i,3*j+c)
4. 验证获取元素代码(Mat转IplImage)
此代码只用于验证多通道元素获取没有错误,具体用的时候最好还是用opencv直接给的吧(见第3小节)
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
IplImage* cvcvt_mat2IplImage(Mat m)
{
int h = m.rows; int w = m.cols;
int nc = m.channels();
IplImage* pImg = cvCreateImage(cvSize(w,h),8,nc);
for (int i = 0;i<h;i++)
{
for(int j = 0;j<w;j++)
{
Vec3b& elem = m.at<Vec3b>(i,j);
for (int c = 0; c<nc; c++)
{
//以下两种都可以
//((uchar*)pImg->imageData+i*pImg->widthStep)[j*3+c] = elem[c];
CV_IMAGE_ELEM(pImg,uchar,i,3*j+c) = elem[c];
}
}
}
return pImg;
}
1、四者关系:
1).CvMat(CvMat is now obsolete, consider using Mat instead)不建议用;
2). 派生关系:CvArr -> CvMat -> IplImage
3). Mat是C++接口,和IplImage有所不同。
2. 相互转换
1). Mat与IplImage相互转换
IplImage* src;
某文章说,转换应该是Mat m(src); 而这不会复制内容,真正能复制内容的是:
Mat -> IplImage:
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
Mat m;
IplImage* transIplimage = cvCloneImage(&(IplImage) m);
IplImage -> Mat
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
IplImage* transIplImage;
Mat m = cvarrToMat(transIplImage,true);
2). CvMat与IplImage相互转换
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
IplImage* transIplImage;
CvMat* cvmat;
cvGetMat(transIplImage,cvmat);
cvGetImage(cvmat,transIplImage);
3. (多通道)Mat, IplImage, CvMat的元素获取
单通道的网上很多,这里只写多通道:
1). IplImage
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//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)
2 ).Mat
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
Mat m;
int h = m.rows; int w = m.cols;
int nc = m.channels();
for (int i = 0;i<h;i++)
{
for(int j = 0;j<w;j++)
{
Vec3b& elem = m.at<Vec3b>(i,j);
for (int c = 0; c<nc; c++)
{
uchar uc = elem[c] ;//Mat(i,j) of channel c
}
}
}
3). CvMat
CV_MAT_ELEM(cvmat,uchar,i,3*j+c)
4. 验证获取元素代码(Mat转IplImage)
此代码只用于验证多通道元素获取没有错误,具体用的时候最好还是用opencv直接给的吧(见第3小节)
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
IplImage* cvcvt_mat2IplImage(Mat m)
{
int h = m.rows; int w = m.cols;
int nc = m.channels();
IplImage* pImg = cvCreateImage(cvSize(w,h),8,nc);
for (int i = 0;i<h;i++)
{
for(int j = 0;j<w;j++)
{
Vec3b& elem = m.at<Vec3b>(i,j);
for (int c = 0; c<nc; c++)
{
//以下两种都可以
//((uchar*)pImg->imageData+i*pImg->widthStep)[j*3+c] = elem[c];
CV_IMAGE_ELEM(pImg,uchar,i,3*j+c) = elem[c];
}
}
}
return pImg;
}
相关文章推荐
- CentOS 7 编译安装 Nginx 1.9.7
- 关于icare贴盒单功能的注意事项-------运维日志9
- 启动ubuntu,出现stopping log initial device creation的解决方法
- hadoop-自定义数据类型
- Mac平台上OpenCV开发环境搭建
- 本地yum源的配置
- linux查找目录下的所有文件中是否含有某个字符串
- ecshop修改后台目录
- hadoop-wordcount
- OpenJudge_P8782 乘积最大(DP)
- opensuse13.2上nfs无法使用
- Hadoop2.6.0学习笔记(七)MapReduce分区
- 如何用linux命令查看nginx是否在正常运行
- OpenJudge_P8780 拦截导弹(非完整)
- nginx安装配置+清缓存模块安装
- nginx 编译参数详解(运维不得不看)
- Linux下JDK.Eclipse.Tomcat安装
- nginx安装(1) – ttlsa教程系列之nginx
- Mysql安装(Centos6.2)
- nginx 配置文件中的 location