OpenCV(三) 之 基本数据结构 CvMat和 IplImage

CvMat
IplImage

OpenCv中基本的数据类型

类型 参数 表示
CvPoint int x,y 像素点
CvPoint2D32f float x,y 平面点
CvPoint3D32f float x,y,z 空间点
CvSize int width,height 图像大小
CvSize2D32f float x, y 区域大小
CvSize3D32f float x,y,z 立方体大小
CvRect int x,y,width,height 矩形区域
CvScalar double val[4] RGBA 值

类型的构造函数仅是类型名首字母小写,比如cvPoint(int x,int y),除了CvScalar

CvScalar类型是可以用来存放4个double类型的数组,最多四个不一定要四个

  1. typedef struct CvScalar 



  2. double val[4]; 

  3. }; 

其赋值函数有四种

  1. 1. CvScalar cvScalar(double v0,double v1,double v2, double v3); 

  2. 2. CvScalar cvRealScalar(double v0); 

  3. //第一个数值赋值,剩余三个为0 

  4. 3. CvScalar cvScalarAll(double v); 

  5. //所有的四个值都相同 

  6. 4. CV_RGB 

  7. #define CV_RGB(r,g,b) cvScalar(b,r,g,0); 

CvMat类型

  1. typedef struct CvMat { 

  2. int type; 

  3. int step; 

  4. int* refcount; // for internal use only 

  5. union { 

  6. uchar* ptr; 

  7. short* s; 

  8. int* i; 

  9. float* fl; 

  10. double* db; 

  11. } data; 

  12. union { 

  13. int rows; 

  14. int height; 

  15. }; 

  16. union { 

  17. int cols; 

  18. int width; 

  19. }; 

  20. } CvMat; 

其构造函数

  1. CvMat* cvCreateMat(int rows,int cols,int type); 

  2. CvMat* cvCreateMatHeader(int rows,int cols,int type); 

  3. CvMat* cvInitMatHeader(CvMat *mat,int rows,int cols,int type, void* data=NULL, int step = CV_AUTOSTEP) 

  4. CvMat* cvCloneMat(CvMat*) 


  5. //内存释放 

  6. void cvReleaseMat(CvMat** mat) 

使用数组创建CvMat

  1. float vals[4]=[1,2,3,4]; 

  2. CvMat* mat; 

  3. cvInitMatHeader(mat,2,2,CV_32FC1,vals); 

CvMat属性值的获取

  1. cvGetElemType(const CvArr* arr);//返回数据类型 

  2. cvGetDims(const CvArr* arr,int* sizes=NULL);//返回CvMat的维数,相当于张量的阶数, int* 可以用来存储每一维对应的长度 

  3. cvGetDimSize(const CvArr* arr,int index);//返回第index维度上的长度 

CvMat数据值的读取

  1. float sum( const CvMat* mat )  



  2. float s = 0.0f; 

  3. for(int row=0; row<mat->rows; row++ )  



  4. const float* ptr = (const float*)(mat->data.ptr + row * mat->step); 

  5. for( col=0; col<mat->cols; col++ ) 



  6. s += *ptr++; 





  7. return( s ); 



这里要注意的是

  1. 要强制指定数据类型,因为CvMat定义中数据类型是union。

  2. 使用step参数是每一行所占的字节数,并不等于cols*sizeof(bytes),因为含有优化的地址对齐问题。

CvMat矩阵数据存储顺序是先行再列,3D数据存储顺序是每个位置的channels,然后按行、列排列。

下图时一组空间点存到不同的CvMat的存储结果

1477837579893.jpg

IplImage

  1. typedef struct _IplImage{ 

  2. int nSize; 

  3. int ID; 

  4. int nChannels; //**type 

  5. int alphaChannel; 

  6. int depth; //**type 

  7. int dataOrder; //数组存储结构,是按照像素存IPL_DATA_ORDER_PIXEL,还是先按照通道存IPL_DATA_ORDER_PLANE 

  8. int origin; //图像坐标原点位于左上角 IPL_ORIGIN_TL,还是左下角IPL_ORIGIN_BL 

  9. int align; 

  10. int width; //**columns 

  11. int height; //**rows 

  12. char colorModel[4]; 

  13. char channelSeq[4]; 

  14. struct _IplROI* roi; //region of interest 

  15. struct _IplImage* maskROI; 

  16. void* imageId; 

  17. struct _IplTileInfo* tileInfo; 

  18. int imageSize; 

  19. char* imageData; //** data 

  20. int widthStep; //** step 

  21. int BorderMode[4]; 

  22. int BorderConst[4]; 

  23. char* imageDataOrigin; 



其中注释**部分对应着CvMat的成员变量,CvMat的type成员被拆分成了两个属性:depth, nChannels表示像素值深度和图像的通道数

depth的取值有

  1. IPL_DEPTH_8U; IPL_DEPTH_8S; IPL_DEPTH_16S; IPL_DEPTH_32S; IPL_DEPTH_32F; IPL_DEPTH_64F; 

看字面就知道什么意思了。

IplROI包含的属性:

  1. int xOffset, yOffset; //x,y 方向的偏置 

  2. int height, width; //感兴趣区域的大小 

  3. int COI; //Channel of Interest,感兴趣的通道 

一旦ROI设置了,那么对图像的操作将尽在ROI内操作。

IplImage数据的访问示例

对于HSV图像,希望将S,V通道值设置为255:

  1. void saturate_sv(IplImage* img) 



  2. for(int y=0;y<img->height;y++) 



  3. uchar* ptr=(uchar*)(img->imageData+y*img->widthStep); 

  4. for(int x=0;x<img->width;i++) 



  5. ptr[3*x+1]=255; 

  6. ptr[3*x+2]=255; 







这里奇怪为什么默认img->dataOrder=IPL_DATA_ORDER_PIXEL。这是因为

We say that dataOrder may be either IPL_DATA_ORDER_PIXEL of IPL_DATA_ORDER_PLANE, but in fact only IPL_DATA_ORDER_PIXEL is supported by OpenCV. Both values are generally supported by IPL/IPP, but OpenCV always uses interleaved images.

Note: 比较CvMat和IplImage数据区的操作,发现IplImage->imageData并没有进行类型转换,全部都是byte字节,而CvMat则需要转换成所存储数据的类型,在指针运算时需要特别注意,尤其是IplImage和CvMat进行计算时。

ROI的使用:

  1. void cvSetImageROI(IplImage* image, CvRect rect); //设置rect区域为感兴趣区域 

  2. void cvResetImageROI(IplImage* image); //取消图像的感兴趣区域 

  1. #include "highgui.h" 

  2. #include "cv.h" 

  3. int main(int argc, char** argv) 



  4. // 图像路径、ROI的x,y偏移量, 长和宽、像素值增加量 

  5. IplImage* src; 

  6. if (argc == 7 && ((src = cvLoadImage(argv[1])) != 0)) 



  7. int xOffset = atoi(argv[2]); //x偏移 

  8. int yOffset = atoi(argv[3]); //y偏移 

  9. int width = atoi(argv[4]); //ROI宽 

  10. int height = atoi(argv[5]); //ROI高 

  11. int add = atoi(argv[6]); //每个像素值增加量 


  12. cvSetImageROI(src, cvRect(xOffset, yOffset, width, height)); 

  13. cvAddS(src, cvScalarAll(add), src); 

  14. cvResetImageROI(src); 

  15. cvNamedWindow("src"); 

  16. cvShowImage("src", src); 

  17. cvWaitKey(0); 

  18. cvReleaseImage(&src); 

  19. cvDestroyWindow("src"); 







1478005187960.jpg

上述过程还存在另一种直接地址操作的方法

  1. #include "highgui.h" 

  2. #include "cv.h" 

  3. int main(int argc, char** argv) 



  4. // 图像路径、ROI的x,y偏移量, 长和宽、像素值增加量 

  5. IplImage* src; 

  6. if (argc == 7 && ((src = cvLoadImage(argv[1])) != 0)) 



  7. int xOffset = atoi(argv[2]); //x偏移 

  8. int yOffset = atoi(argv[3]); //y偏移 

  9. int width = atoi(argv[4]); //ROI宽 

  10. int height = atoi(argv[5]); //ROI高 

  11. int add = atoi(argv[6]); //每个像素值增加量 


  12. IplImage * sub_img = cvCreateImageHeader(cvSize(width, height), src->depth, src->nChannels); 

  13. sub_img->widthStep = src->widthStep; 

  14. sub_img->imageData = src->imageData + yOffset*src->widthStep + xOffset*src->nChannels; 


  15. cvAddS(sub_img, cvScalarAll(add), sub_img); 

  16. cvReleaseImageHeader(&sub_img); 


  17. cvResetImageROI(src); 

  18. cvNamedWindow("src"); 

  19. cvShowImage("src", src); 

  20. cvWaitKey(0); 

  21. cvReleaseImage(&src); 

  22. cvDestroyWindow("src"); 







这里很容易理解,就是将ROI截取出来作为一个新的图像,需要注意的时sub_img并没有新分配地址,数据区指向的仍然是src的数据区,此时图像sub_img的数据区并不是连续的,所以将src->widthStep赋值给sub_img-》widthStep保证读取正确的地址数据。

OpenCV(三) 之 基本数据结构 CvMat和 IplImage的更多相关文章

  1. OpenCV数据结构:CvMat,IplImage,CvArr的应用

    最近看HS算法时,发现在新的OpenCV3.0已经移除了该算法,于是不得不看老版的.这其中涉及到了CvMat,CvArr,IplImage的使用.关于这三个结构与Mat的转换关系,总结如下: (1)派 ...

  2. OpenCV——Mat、CvMat、IplImage类型浅析【转】

    OpenCV中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage. 一.Mat类型:矩阵类型,Matrix. 在openCV中,Mat是一个多维的密集数据数组.可以用来处理向量和矩阵 ...

  3. Opencv中将CvMat转为IplImage

    Opencv中将CvMat转为IplImage,并在内存获得起头指针,而不用cvSaveImage(),贴上代码 IplImage * imgg = NULL; imgg = cvCreateImag ...

  4. OpenCV学习(2)--基本数据结构

    OpenCV的基本数据结构 CvPoint:表示图像中的点 CvPoint2D32f:二维空间中的点 CvPoint3D32f:三维空间中的点 这些都是结构体,并不是C++语言中的类,所以他们的构造函 ...

  5. CvArr、Mat、CvMat、IplImage、BYTE转换

    一.Mat类型:矩阵类型,Matrix.     在openCV中.Mat是一个多维的密集数据数组. 能够用来处理向量和矩阵.图像.直方图等等常见的多维数据.     Mat有3个重要的方法:     ...

  6. 图像处理之opencv---mat、cvmat、IplImage之间的转换

    一.Mat类型:矩阵类型,Matrix.  在openCV中,Mat是一个多维的密集数据数组.可以用来处理向量和矩阵.图像.直方图等等常见的多维数据. Mat有3个重要的方法: 1.Mat mat = ...

  7. 【转】Cvmat与IplImage的相互转换

    seyvlei 原文地址 1.IplImage转Cvmat IplImage* src = cvLoadImage(); CvMat* mat=cvCreateMat(src->height,s ...

  8. 《学习opencv》笔记——基本数据结构,CvMat,矩阵訪问

        老板让让做一个东东.输入端要用到opencv顺便就来学习一下.买了本书<学习opencv>翻来一看,opencv1.0,去官网上一看.opencv2.49,瞬间有种蛋碎的赶脚.看着 ...

  9. opencv常用数据结构之:IplImage

    typedef struct_IplImage{      int nSize; //IplImage大小      int ID; //版本(=0)      int nChannels; //大多 ...

随机推荐

  1. 通过ip查询对方位置

    我们这里使用的是baidumap的高精度IP定位API的接口,具体说明可以参考baidu提供的文档 使用前需要申请一个AK密钥类似于Kgcx......................xxl8w的样式 ...

  2. eclipse逐步调试

    Eclipse 的单步调试 1.设置断点在程序里面放置一个断点,也就是双击需要放置断点的程序左边的栏目上.2.调试(1)点击"打开透视图"按钮,选择调试透视图,则打开调试透视图界面 ...

  3. CI 扩展 Service

    CI 扩展 Service 说明 CodeIgniter是一套典型的MVC框架,M负责数据,C负责交互,V负责视图,但是随着业务逻辑越来越复杂, 必然会涉及到一些列操作过程,例如用户下订单,就会存在校 ...

  4. MySQL索引背后的数据结构及算法原理【转】

    本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...

  5. 不常用的SQL语句记录

    只知道字段名,查询哪些表有该字段:假如字段名为Index select sysobjects.name as tablename,syscolumns.name as columnname from  ...

  6. STM32F412应用开发笔记之四:与远红外炭氢传感器通讯

    远红外炭氢传感器是在多组分气体传感器中用来检测甲烷和丙烷浓度的,采用单总线串行通讯,TTL电平.所以我们需要用到UART口来实现与远红外炭氢传感器的通讯. 远红外传感器就是这个样子的: 再来一张进气和 ...

  7. PLSQLDeveloper 常用设置

    PLSQL Developer常用设置及快捷键   1.登录后默认自动选中My Objects (已验证可用)   默认情况下,PLSQL Developer登录后,Brower里会选择All obj ...

  8. C# 操作excel单元格居中

    C# 操作excel //导出Excel        private void ExportExcel(string fileName, System.Data.DataTable myDGV, s ...

  9. Python之实用的IP地址处理模块IPy

    实用的IP地址处理模块IPy 在IP地址规划中,涉及到计算大量的IP地址,包括网段.网络掩码.广播地址.子网数.IP类型等 别担心,Ipy模块拯救你.Ipy模块可以很好的辅助我们高效的完成IP的规划工 ...

  10. 订货(bzoj 2424)

    Description 某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初的库存量为零,第n月月底的库存量也为 ...