cvarr,cvmat,iplimage关系
- 格式:doc
- 大小:12.26 KB
- 文档页数:1
OpenCV2:总结篇cv::Mat类⼀.简介在OpenCV中,可以⽤C++语法的Mat类来表⽰⼀张图像也可以⽤C语法的lpllmage或CvMat结构体来表⽰⼀张图像1.单通道像素值2.多通道像素值OpenCV默认颜⾊顺序为BGR⼆.成员公有函数cv::Mat类能够⾃动管理内存,由矩阵头和指向存储所有像素值的矩阵的指针构成cv::Mat类表⽰⼀个n维的密集数值单通道或多通道数组,它可⽤于存储实数或复数值的向量和矩阵灰度和彩⾊图像体素向量场点云张量直⽅图等1.常⽤的成员函数Mat::Mat()Mat::~Mat()Mat::row // 创建⼀个具有指定了矩阵头中⾏数的参数的矩阵Mat::col // 创建⼀个具有指定了矩阵头中列数的参数的矩阵Mat::rowRange // 为指定的⾏span创建⼀个新的矩阵头,可取指定⾏区间元素Mat::colRange // 为指定的列span创建⼀个⼼得矩阵头,可取指定列区间元素Mat::clone // 创建⼀个数据及其基础数据的完整副本Mat::copyTo //Mat::convertToMat::zerosMat::onesMat::channelsMat::emptyMat::atMat::isContinuous() //判断图像存储是否连续2.不常⽤的成员函数Mat::addref()Mat::adjustROI()Mat::assignTo()Mat::at()Mat::begin()Mat::channels() Mat::checkVertor() Mat::clone() Mat::col() Mat::colRange() Mat::convertTo() Mat::copySize() Mat::copyTo() Mat::create() Mat::cross() Mat::deallocate() Mat::depth() Mat::diag() Mat::dot() Mat::elemSize() Mat::elemSize1() Mat::empty() Mat::end() Mat::eye() Mat::inv() Mat::isContinuous() Mat::isSubmatrix() Mat::locateROI() Mat::mul() Mat::ones() Mat::pop_back() Mat::ptr() Mat::push_back() Mat::push_back_() Mat::release() Mat::reserve() Mat::reshape() Mat::resize() Mat::row() Mat::rowRange() Mat::setTo() Mat::step1() Mat::t()Mat::total()Mat::type()Mat::zeros()3.成员数据class CV_EXPORTS Mat{public:// 标志位int flags;// 矩阵的维数,应该⼤于等于2int dims;// 矩阵的⾏数和列数,如果维度⼤于2,则都为-1int rows,cols;// 指向数据的指针uchar* data;// 指向引⽤计数的指针int* refcount;uchar* datastart;uchar* dataend;uchar* datalimit;MatAllocator* allocator;MSize size;MStep step;};4.构造函数Mat() // 默认构造函数Mat(int row,int cols,int type)Mat(Size size,int type)Mat(int rows,int cols,int type,const Scalar& s)Mat(Size size,int type,const Scalar& s)Mat(int ndims,const int* sizes,int type)Mat(int ndims,const int* sizes,int type,const Scalar& s)Mat(const Mat& m) // 拷贝构造函数Mat(int rows,int cols,int type,void* data,size_t step=AUTO_STEP)Mat(Size size,int type,void* data,size_t step=AUTO_SETP)Mat(int ndims,const int* sizes,int type,void* data,const size_t* steps=0)Mat(const Mat& m,const Range& rowRange,const Range& colRange=Range::all());Mat(const Mat& m,const Rect& roi);Mat(const Mat& m,const Range* ranges);Mat(const CvMat* m,bool copyData=false);Mat(const CvMatND* m,bool copyData=false);Mat(const IplImage* img,bool copyData=false);template<typename _Tp>explicit Mat(const vector<_Tp>& vec,bool copyData=false);template<typename _Tp,int n>explicit Mat(const Vec<_Tp,n>& vec,bool copyData=true);template<typename _tp,>三.cv::Mat 类型转换1.cv::Mat 类转换为 IplImage 类型和 CvMat 类型cv::Mat img;CvMat cvMatImg = img;IplImage iplImage = img;2.IpIImage 类型和 CvMat 类型转换为 cv::Mat 类型IplImage* iplImg = cvLoadImage("a.jpg");cv::Mat img(iplImg, true);。
CvArr、Mat、CvMat、IplImage、BYTE转换(总结而来)分类:OpenCv 2012-02-29 14:165388人阅读评论(2)收藏举报byte优化图像处理数据结构matrixvector一、Mat类型:矩阵类型,Matrix。
在openCV中,Mat是一个多维的密集数据数组。
可以用来处理向量和矩阵、图像、直方图等等常见的多维数据。
Mat有3个重要的方法:1、Mat mat = imread(const String* filename); 读取图像2、imshow(const string frameName, InputArray mat); 显示图像3、imwrite (const string& filename, InputArray img); 储存图像Mat类型较CvMat与IplImage类型来说,有更强的矩阵运算能力,支持常见的矩阵运算。
在计算密集型的应用当中,将CvMat与IplImage类型转化为Mat类型将大大减少计算时间花费。
A.Mat -> IplImage同样只是创建图像头,而没有复制数据。
例:// 假设Mat类型的imgMat图像数据存在IplImage pImg= IplImage(imgMat);B.Mat -> CvMat与IplImage的转换类似,不复制数据,只创建矩阵头。
例:// 假设Mat类型的imgMat图像数据存在CvMat cvMat = imgMat;二、CvMat类型与IplImage类型:“图像”类型在openCV中,Mat类型与CvMat和IplImage类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。
而CvMat 和IplImage类型更侧重于“图像”,openCV对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。
补充:IplImage由CvMat派生,而CvMat由CvArr派生即CvArr -> CvMat -> IplImage CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat 处理。
opencv⾥⾯CV_32FC1家族因为总是接触过这样⼀些#define⾥⾯的东西但是总也不知道是⼲什么⽤的。
⽽且每看⼀次梦⽐⼀次。
对于这些东西到底是什么的简写根本就不能理解。
原意是跑⼀下这个例程的:cvRectangle(myMat,cvPoint(5, 10),cvPoint(20, 30),cvScalar(50, 50, 200));可是第⼆章就练习了 IplImage这个结构,对于cvMat简直就不知所云,然后第⼀版:CvMat *myMat;cvRectangle(myMat,cvPoint(5, 10),cvPoint(20, 30),cvScalar(50, 50, 200));然后就想显⽰,这必然是不能跑,因为没有实例化,没有分配内存空间,还想在所谓的画布上画图像,应该是不⾏。
所以找来了明杰同学,他也是很热⼼的但是说对于这个cvmat也不是很熟。
于是就这样跑起来了。
IplImage *myImg=cvCreateImage(cvSize(500,500),8,3);cvZero(myImg);cvRectangle(myImg,cvPoint(5, 10),cvPoint(20, 30),cvScalar(50, 50, 200));cvNamedWindow("Example6", CV_WINDOW_AUTOSIZE);cvShowImage("Example6", myImg);cvWaitKey(0);能跑了好开⼼,然后看着他帮我调颜⾊也就是cvScalar 我想这个单词应该是读作:color的把就跟class都写成成clazz⼀样。
/*然后跟我熟悉的rgb有出⼊的点在于这个⾥⾯是bgr也就是第⼀个参数是蓝⾊第⼆个是绿⾊第三个参数是红⾊,我记得不论是我之前的ps课程还是后⾯的⼀些android的点,或者h5⾥⾯那个颜⾊都是rgb的。
前几天被OpenCV的直方图的数据结构CvHistogram弄得很纠结。
上网一搜,也没什么相关的资料。
现在有点头绪了,就写点东西,让后面的人好走一些吧。
先来看看CvHistogram的定义:typedef struct CvHistogram{int type;CvArr* bins;float thresh[CV_MAX_DIM][2]; /* For uniform histograms. */float** thresh2; /* For non-uniform histograms. */CvMatND mat; /* Embedded matrix header for array histograms. */}CvHistogram;第一个成员type,相信大家都见过很多结构都有其。
比如:CvMat、CvMatND、IplImage(图像结构中,其用nSize成员代替)。
这个成员用来区分各个类型的。
OpenCV很多函数的原型都用到了一个CvArr*类型。
这个类型说明可以接受一个CvMat或者IplImage类型的指针。
这是我们对它的最初理解。
其实,看过CvArr定义的人都知道,其实是typedef void CvArr;并非派生关系。
对于OPenCV函数内部,得到的是一个void指针,这时就有必要确切的知道得到的到底是一个什么类型(是CvMat指针还是IplImage指针,还是CvMatND指针)。
这样type的作用就体现了。
第二个成员bins。
一个CvArr(即void)指针。
大家可以先把其理解成一个快捷方式。
其等于mat成员的data成员。
等一下再说这个成员。
第三个成员是thresh。
是一个二维数组。
而且第二维是2.设想一下,这个函数是求图像的分布像素值(像素灰度值)分布情况。
而不同的人,对不同的灰度值感兴趣。
这时,OpenCV就必须能够让用户自行指定一个灰度值的范围。
这就需要一个上界和下界来指定一个范围。
opencv中Mat、cvMat、IplImage、CvvImage之间转换1、CvMat之间的复制//注意:深拷贝 - 单独分配空间,两者相互独⽴CvMat* a;CvMat* b = cvCloneMat(a); //copy a to b2、Mat之间的复制//注意:浅拷贝 - 不复制数据只创建矩阵头,数据共享(更改a,b,c的任意⼀个都会对另外2个产⽣同样的作⽤)Mat a;Mat b = a; //a "copy" to bMat c(a); //a "copy" to c//注意:深拷贝Mat a;Mat b = a.clone(); //a copy to bMat c;a.copyTo(c); //a copy to c3、CvMat转Mat//使⽤Mat的构造函数:Mat::Mat(const CvMat* m, bool copyData=false); 默认情况下copyData为falseCvMat* a;//注意:以下三种效果⼀致,均为浅拷贝Mat b(a); //a "copy" to bMat b(a, false); //a "copy" to bMat b = a; //a "copy" to b//注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据)Mat b = Mat(a, true); //a copy to b4、Mat转CvMat//注意:浅拷贝Mat a;CvMat b = a; //a "copy" to b//注意:深拷贝Mat a;CvMat *b;CvMat temp = a; //转化为CvMat类型,⽽不是复制数据cvCopy(&temp, b); //真正复制数据 cvCopy使⽤前要先开辟内存空间==========IplImage与上述⼆者间的转化和拷贝===========1、IplImage之间的复制这个不赘述了,就是cvCopy与cvCloneImage使⽤区别,贴张⽹上的图:2、IplImage转Mat//使⽤Mat的构造函数:Mat::Mat(const IplImage* img, bool copyData=false); 默认情况下copyData为falseIplImage* srcImg = cvLoadImage("Lena.jpg");//注意:以下三种效果⼀致,均为浅拷贝Mat M(srcImg);Mat M(srcImg, false);Mat M = srcImg;//注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据)Mat M(srcImg, true);3、Mat转IplImage//注意:浅拷贝 - 同样只是创建图像头,⽽没有复制数据Mat M;IplImage img = M;IplImage img = IplImage(M);//深拷贝cv::Mat img2;IplImage imgTmp = img2;IplImage *input = cvCloneImage(&imgTmp);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); //深拷贝6、CvvImage与IplImage相互转化利⽤CvvImage可以⽅便地在MFC中画图(DrawToHdc函数),但是在调⽤Copyof这个函数时,要写成 CvvImage img; IplImage src; img.Copyof( src, src->nChannels);否则,如果写成img.Copyof(src),src是单通道的话,会出现错误! CvvImage不仅能处理3通道,也能处理单通道。
OpenCV中IplImage,CvMat,Mat基本使用和元素遍历OpenCV中IplImage, CvMat, Mat 基本使用和元素遍历opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像。
在OpenCV的文档中说明Mat类型通过C++面向对象的方法实现的,可以进行Matlab风格的矩阵操作,IplImage类型和CvMat类型用C语言实现的,两者之间存在着类似于面向对象中的继承关系。
•IplImage一、先上OpenCV中的图像信息头,该结构体的定义如下:[cpp]view plaincopy1.typedef struct _IplImage2.{3.int nSize; /* IplImage大小 */4.int ID; /* 版本 (=0)*/5.int nChannels; /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */6.int alphaChannel; /* 被OpenCV忽略 */7.int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,8.IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_ DEPTH_64F 可支持 */9.10.char colorModel[4]; /* 被OpenCV忽略 */11.char channelSeq[4]; /* 被OpenCV忽略 */12.int dataOrder; /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道. cvCreateImage只能创建交叉存取图像 */13.int origin; /* 0 - 顶—左结构,1 - 底—左结构 (Windows bitmaps 风格) */14.int align; /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */15.16.int width; /* 图像宽像素数 */17.int height; /* 图像高像素数*/18.19.struct _IplROI *roi; /* 图像感兴趣区域. 当该值非空只对该区域进行处理 */20.struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */21.void *imageId; /* 同上*/22.struct _IplTileInfo *tileInfo; /*同上*/23.24.int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/25.char *imageData; /* 指向排列的图像数据 */26.int widthStep; /* 排列的图像行大小,以字节为单位 */27.int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */28.int BorderConst[4]; /* 同上 */29.30.char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */31.} IplImage;特别说明:(1)dataOrder这个可以取两个不同的值(0/1),其中交叉存取颜色通道:指颜色数据排列会是BGRBGR....分开颜色通道:几个颜色通道就分几个颜色平面存储。
opencv中cvarrcvmatiplimagecvmat和cvinputarray的相关总结1.CvArr* :[cpp] view plain copy print?typedef void CvArr;可以认为CvArr*是一个万能指针,例如某个函数参数是CvArr*,该函数内部会强制转换回该函数需要的数据类型,所以在调用该函数时,传入的参数类型就必须与该函数要求的类型一致,否则就会出错。
2.cv::Mat:我们可以认为cv::Mat类型把向量、矩阵、图像等都统一了操作。
cv::Mat有更强大的矩阵运算能力,支持常见的矩阵运算。
对于图像数据的运算,将IplImage和CvMat 类型转换成cv::Mat类型可大大提高运算效率(后面会将cv::Mat与IplImage和CvMat类型之间的转换)。
2.1 cv::Mat的一些操作[cpp] view plain copy print?cv::Mat mat = imread(const string* filename); //读取图像imshow(const string Window's name, mat); //显示图像imwrite(const string&filename, mat); //将mat图像保存到固定路径中3.IplImage:现在OpenCV的很多处理图像的函数中都使用IplImage* 这个数据类型,下面是它的一些重要的操作:[cpp] view plain copy print?IplImage* img =cvLoadImage(PathName); //从路径中加载图像到img cvShowImage("WindowName", img); //显示图像img cvWaitKey();//按任意键退出窗口4.CvMat:因为CvMat是矩阵结构,无法像IplImage和Mat一样直接读取图像数据,而是要先创建Mat类的空矩阵(cvCreateMat());再利用宏CV_MAT_ELEM()存放数据,或者提取数据。