转载请注明出处:http://blog.csdn.net/xiaowei_cqu/article/details/7557063

!!此篇是基于IplImage* (C接口或者说2.1之前版本的接口,新的Mat的访问方式请参考博文:
《访问Mat图像中每个像素的值》)

IplImage是OpenCV中CxCore部分基础的数据结构,用来表示图像,其中Ipl是Intel Image Processing Library的简写。以下是IplImage的结构分析(来自OpenCV中文网站:http://www.opencv.org.cn/index.php/Cxcore%E5%9F%BA%E7%A1%80%E7%BB%93%E6%9E%84#IplImage)

[cpp] view plaincopy
  1. typedef struct _IplImage
  2. {
  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. char colorModel[4]; /* 被OpenCV忽略 */
  10. char channelSeq[4]; /* 同上 */
  11. int  dataOrder;     /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道.
  12. cvCreateImage只能创建交叉存取图像 */
  13. int  origin;        /* 0 - 顶—左结构,
  14. 1 - 底—左结构 (Windows bitmaps 风格) */
  15. int  align;         /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */
  16. int  width;         /* 图像宽像素数 */
  17. int  height;        /* 图像高像素数*/
  18. struct _IplROI *roi;/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */
  19. struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */
  20. void  *imageId;     /* 同上*/
  21. struct _IplTileInfo *tileInfo; /*同上*/
  22. int  imageSize;     /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/
  23. char *imageData;  /* 指向排列的图像数据 */
  24. int  widthStep;   /* 排列的图像行大小,以字节为单位 */
  25. int  BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */
  26. int  BorderConst[4]; /* 同上 */
  27. char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
  28. }
  29. IplImage;

直接访问:

对我们来说比较重要的两个元素是:char *imageData以及widthStep。imageData存放图像像素数据,而widStep类似CvMat中的step,表示以字节为单位的行数据长度。

一个m*n的单通道字节型图像,其imageData排列如下:

如果我们要遍历图像中的元素,只需:

[cpp] view plaincopy
  1. IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
  2. uchar* tmp;
  3. for(int i=0;i<img->height;i++)
  4. for(int j=0;j<img->width;j++)
  5. *tmp=((uchar *)(img->imageData + i*img->widthStep))[j];

这种直接访问的方法速度快,但容易出错,我们可以通过定义指针来访问。即:

[cpp] view plaincopy
  1. IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
  2. ucha* data=(uchar *)img->imageData;
  3. int step = img->widthStep/sizeof(uchar);
  4. uchar* tmp;
  5. for(int i=0;i<img->height;i++)
  6. for(int j=0;j<img->width;j++)
  7. *tmp=data[i*step+j];

而多通道(三通道)字节图像中,imageData排列如下:

其中(Bi,Bj)(Gi,Gj)(Ri,Rj)表示图像(i,j)处BGR分量的值。使用指针的遍历方法如下:

[cpp] view plaincopy
  1. IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
  2. IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
  3. uchar* data=(uchar *)img->imageData;
  4. int step = img->widthStep/sizeof(uchar);
  5. int channels = img->nChannels;
  6. uchar *b,*g,*r;
  7. for(int i=0;i<img->height;i++)
  8. for(int j=0;j<img->width;j++){
  9. *b=data[i*step+j*chanels+0];
  10. *g=data[i*step+j*chanels+1];
  11. *r=data[i*step+j*chanels+2];
  12. }

*如果要修改某像素值,则直接赋值。

使用cvGet2D()函数访问:

cvGet*D系列函数可以用来返回特定位置的数组元素(一般使用cvGet2D),原型如下:
[cpp] view plaincopy
  1. CvScalar cvGet1D( const CvArr* arr, int idx0 );
  2. CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );
  3. CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
  4. CvScalar cvGetND( const CvArr* arr, int* idx );

idx0,idx1,idx2分别用来指示元素数组下标,即cvGet2D返回(idx0,idx1)处元素的值。

因此,单通道图像像素访问方式如下:
[cpp] view plaincopy
  1. IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
  2. double tmp;
  3. for(int i=0;i<img->height;i++)
  4. for(int j=0;j<img->width;j++)
  5. tmp=cvGet2D(img,i,j).val[0];

多通道字节型/浮点型图像:

[cpp] view plaincopy
  1. IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
  2. double tmpb,tmpg,bmpr;
  3. for(int i=0;i<img->height;i++)
  4. for(int j=0;j<img->width;j++){
  5. tmpb=cvGet2D(img,i,j).val[0];
  6. tmpg=cvGet2D(img,i,j).val[1];
  7. tmpr=cvGet2D(img,i,j).val[2];
  8. }
如果是修改元素的值,可用cvSet*D(一般是cvSet2D)函数:
[cpp] view plaincopy
  1. void cvSet1D( CvArr* arr, int idx0, CvScalar value );
  2. void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );
  3. void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );
  4. void cvSetND( CvArr* arr, int* idx, CvScalar value );

这种方法对于任何图像的访问方式是一样的,比较简单,但效率较低,不推荐使用。

访问图像中每个像素的值相关推荐

  1. OpenCV访问Mat图像中每个像素的值

    原文:http://blog.csdn.net/xiaowei_cqu/article/details/7771760 matlab中, a=[1,2,3;4,5,6;7,8,9] a(1,2) 第一 ...

  2. 《OpenCV3编程入门》学习笔记5 Core组件进阶(一)访问图像中的像素

    第5章 Core组件进阶 5.1 访问图像中的像素 5.1.1 图像在内存中的存储方式 1.图像矩阵大小取决于通道数,矩阵中的子列个数与通道数相等. 2.如果内存足够大,可以实现连续存储,有助于提升图 ...

  3. 访问Mat中每个像素的值

    Color Reduce 还是使用经典的Reduce Color的例子,即对图像中的像素表达进行量化.如常见的RGB24图像有256×256×256中颜色,通过Reduce Color将每个通道的像素 ...

  4. 【OpenCV】OpenCV实战从入门到精通之 -- 访问图像中的像素

    目录 1.图像在内存之中的存储方式 2.颜色空间缩减 3.LUT函数:Look up table操作 4.计时函数 5.访问图像中像素的三类方法 5.1.指针访问像素 5.2.迭代器操作像素 5.3. ...

  5. opencv计算图像亮度调节_【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整...

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  6. 【OpenCV】OpenCV函数精讲之 -- 访问图像中的像素

    图像在内存之中的存储方式: 图像矩阵的大小取决于所用的颜色模型,确切说,取决于所用通道数.如果是灰度图像,矩阵就会如图5.1所示. 对于多通道图像来说,矩阵中的列会包含多个子列,其子列个数与通道数相同 ...

  7. 【OpenCV】OpenCV函数精讲之 -- 访问图像中的像素--计时函数

    计时函数: 简便的计时函数:getTickCount()和get TickFrequency() getTickCount()函数:返回CPU自某个事件以来走过的时钟周期数 getTickFreque ...

  8. ITK:在一张图像中设置像素值

    ITK:在一张图像中设置像素值 内容提要 输出结果 C++实现代码 内容提要 本示例演示如何设置图像中单个像素的值. 输出结果 C++实现代码 #include "itkImage.h&qu ...

  9. python获取图片像素矩阵_用python处理图片实现图像中的像素访问

    这篇文章主要介绍了关于用python处理图片实现图像中的像素访问,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 前面的一些例子中,我们都是利用Image.open()来打开一幅图像,然 ...

最新文章

  1. Linux中source命令的用法
  2. Java数据库 高级查询
  3. 机器学习算法加强——SVM实践
  4. 全国计算机二级考试c语言指针,全国计算机二级考试C语言 指针精讲课件.ppt
  5. ASP.NET Core跨域设置
  6. metasploit中msf批量监测
  7. 手机 人人网android 2.2,人人网客户端安卓版
  8. 计算机源代码可以用中文吗,为什么很多人说电脑程序不能使用中文呢?
  9. pytorch一小时速成
  10. 7、Spring事务配置下篇
  11. 常见的行业认证和资质清单介绍
  12. mysql中字符串拼接函数_MySQL 字符串连接CONCAT()函数
  13. Fruit 有上下限的母函数
  14. qlv转mp4格式工厂失败
  15. android wear手表6,Android Wear(手表)开发
  16. UART介绍版(勿看简单介绍)
  17. 微信小程序云开发,快速生成短信验证码
  18. 图片展示门户软件PicHome
  19. 计算机初级考试题库网络管理,计算机基础考试题库(含答案)【精】.doc
  20. pmbok电子版_【员工亲历PMP学习分享】用技巧方法,让PMBOK知识点烂熟于心清晖安安...

热门文章

  1. 陈一舟:每个人风口来的时间不一样
  2. 小工匠聊架构 - 分布式缓存技术
  3. 传递list对象作为参数_24.scala的隐式参数
  4. Mybatis中的attempted to return null from a method with a primitive return type (int).异常
  5. java里面快速排序_Java:快速排序
  6. mysql pdo使用存储过程_PDO调用存储过程的问题
  7. echarts formatter_手把手教你玩转echarts(二)折线图
  8. 485不用双绞线可以吗_加装迎宾踏板可以吗?检车时用不用拆啊?
  9. python判断点在矩形内_Python测试点是否在矩形中
  10. java gzip xml_Java GZIPInputStream与GZIPOutputStream的使用示例