opencv2.1版本之前使用IplImage*数据结构来表示图像,2.1之后的版本使用图像容器Mat来存储。IplImage结构体如下所示。

 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;  

1、使用指针遍历图像像素

(1)单通道字节型图像像素访问

 1 /*2 @author:CodingMengmeng3 @theme:Read the image pixel values4 @time:2017-3-16 11:27:315 @blog:http://www.cnblogs.com/codingmengmeng/6 */7 #include <cv.h>  8 #include <highgui.h>  9 using namespace std;
10 using namespace cv;
11 int main(void)
12 {
13     IplImage* imgSrc = cvLoadImage("./inputData\\shuke1.jpg",0);
14     uchar* pixel = new uchar;
15     for (int i = 0; i < imgSrc->height; i++)
16     {
17         for (int j = 0; j < imgSrc->width; j++)
18         {
19             pixel = (uchar*)(imgSrc->imageData + i*imgSrc->widthStep+j);
20             cout << "pixel=" <<(*pixel)+0<< endl;//+0隐式转换为整型,否则会打印出字符
21         }
22     }
23     delete pixel;24     return 0;
25 }

输出结果是0-255灰度级的灰度值。

其中(uchar*)(imgSrc->imageData + i*imgSrc->widthStep+j)的具体含义:

(a)imgSrc->imageData指向图像第一行的首地址,i是指当前像素点所在的行,widthStep是指图像每行所占的字节数;所以imgSrc->imageData + i*imgSrc->widthStep表示该像素点所在行的首地址;j表示当前像素点所在列,所以imgSrc->imageData + i*imgSrc->widthStep+j即表示该像素点的地址。而因为IplImage->ImageData 的默认类型是 char 类型,所以再对图像像素值进行操作时,要使用强制类型转换为unsigned char,再对其进行处理。否则,图像像素值中,会有负值出现。

(b)widthStep表示存储一行像素需要的字节数

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

因为opencv分配的内存是按4字节对齐的,所以widthStep必须是4的倍数,如果8U图像宽度为3,那么widthStep是4,加一个字节补齐。这个图像的一行需要4个字节,只使用前3个,最后一个空在那儿不用。也就是一个宽3高3的图像的imageData数据大小为4*3=12字节。

(2)三通道字节型图像像素访问

多通道字节型图像的imageData排列如下:

其中(Bi,Bj)(Gi,Gj)(Ri,Rj)表示图像(i,j)处BGR分量的值。

 1 /*2 //@author:CodingMengmeng3 //@theme:Read the image pixel values4 //@time:2017-3-16 11:59:175 //@blog:http://www.cnblogs.com/codingmengmeng/6 */7 #include <cv.h>  8 #include <highgui.h>  9 using namespace std;
10 using namespace cv;
11 int main(void)
12 {
13     IplImage* imgSrc = cvLoadImage("./inputData\\shuke1.jpg");
14     uchar* b_pixel = new uchar;
15     uchar* g_pixel = new uchar;
16     uchar* r_pixel = new uchar;
17     for (int i = 0; i < imgSrc->height; i++)
18     {
19         for (int j = 0; j < imgSrc->width; j++)
20         {
21             b_pixel = (uchar*)(imgSrc->imageData + i*imgSrc->widthStep + (j*imgSrc->nChannels + 0));
22             g_pixel = (uchar*)(imgSrc->imageData + i*imgSrc->widthStep + (j*imgSrc->nChannels + 1));
23             r_pixel=(uchar*)(imgSrc->imageData + i*imgSrc->widthStep + (j*imgSrc->nChannels + 2));
24             cout << "b_pixel=" << *b_pixel+0 << endl;
25             cout << "g_pixel=" << *g_pixel+0 << endl;
26             cout << "r_pixel=" << *r_pixel+0 << endl;
27             cout << "/********************************************/" << endl;
28         }
29     }
30     delete b_pixel;
31     delete g_pixel;
32     delete r_pixel;
33     return 0;
34 }

运行结果:

2、使用cvGet2D()函数访问

cvGet*D系列函数可以用来返回特定位置的数组元素(一般使用cvGet2D),原型如下:

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 );  

(1)单通道图像像素访问

 1 /*2 @author:CodingMengmeng3 @theme:Read the image pixel values4 @time:2017-3-16 15:12:575 @blog:http://www.cnblogs.com/codingmengmeng/6 */7 #include <cv.h>  8 #include <highgui.h>  9 using namespace std;
10 using namespace cv;
11 int main(void)
12 {
13     IplImage* imgSrc = cvLoadImage("./inputData\\shuke1.jpg",0);
14     CvScalar pixel_v;
15     /*
16     CvScalar是一个可以用来存放4个double数值的数组
17     一般用来存放像素值(不一定是灰度值哦)的,最多可以存放4个通道的
18     如何赋值:
19     a) 存放单通道图像中像素:cvScalar(255);
20     b) 存放三通道图像中像素:cvScalar(255,255,255);
21     c)只使用第一个通道,val[0]=val0;等同于cvScalar(val0,0,0,0);
22     */
23     for (int i = 0; i < imgSrc->height; i++)
24     {
25         for (int j = 0; j < imgSrc->width; j++)
26         {
27             pixel_v = cvGet2D(imgSrc, i, j);
28             cout << "pixel=" << pixel_v.val[0] << endl;
29         }
30     }
31     return 0;
32 }

注意:

对于图像中的某一像素点 P(x, y), 在我们正常的坐标系中,x代表其横坐标,y代表其纵坐标;而在opencv的函数cvGet2D()的函数原型是 : CvScalar cvGet2D (const CvArr * arr, int idx0, int idx1); 函数返回的是一个CvScalar 容器,其参数中也有两个方向的坐标,但跟我们平常习惯的坐标不一样的是,idx0代表是的行,即高度,对应于我们平常坐标系的y, idx1代表的是列,即宽度,对应于我们平常坐标系的x使用时请千万别弄反,否则容易出现溢出引发异常。

(2)多通道字节型/浮点型图像像素访问

 1 /*2 @author:CodingMengmeng3 @theme:Read the image pixel values4 @time:2017-3-16 15:18:295 @blog:http://www.cnblogs.com/codingmengmeng/6 */7 #include <cv.h>  8 #include <highgui.h>  9 using namespace std;
10 using namespace cv;
11 int main(void)
12 {
13     IplImage* imgSrc = cvLoadImage("./inputData\\shuke1.jpg");
14     CvScalar pixel_v;
15     /*
16     CvScalar是一个可以用来存放4个double数值的数组
17     一般用来存放像素值(不一定是灰度值哦)的,最多可以存放4个通道的
18     如何赋值:
19     a) 存放单通道图像中像素:cvScalar(255);
20     b) 存放三通道图像中像素:cvScalar(255,255,255);
21     c)只使用第一个通道,val[0]=val0;等同于cvScalar(val0,0,0,0);
22     */
23     for (int i = 0; i < imgSrc->height; i++)
24     {
25         for (int j = 0; j < imgSrc->width; j++)
26         {
27             pixel_v = cvGet2D(imgSrc, i, j);
28             cout << "b_pixel=" << pixel_v.val[0] << endl;//B分量
29             cout << "g_pixel=" << pixel_v.val[1] << endl;//G分量
30             cout << "r_pixel=" << pixel_v.val[2] << endl;//R分量
31             cout << "/********************************************/" << endl;
32         }
33     }
34     return 0;
35 }

运行结果:

それでも私の大好きな人

转载自:http://www.cnblogs.com/codingmengmeng/p/6559724.html

Opencv--IplImage访问图像像素的值相关推荐

  1. Emgu CV4图像处理之访问图像像素通道值7(C#)

    本文测试环境: win10  64位 vistual studio 2019 Emgu CV 4.6.0 环境配置准备: 1 新增控制台项目,.net framework为4.7.2 2  把win- ...

  2. c++ opencv数字图像处理:访问图像像素,遍历图像像素

    文章目录 前言 一.访问图像像素 1.访问(j,i)处像素 2.例子:在图像中加入白色椒盐噪声 二.遍历图像像素 1.指针扫描 2.opencv自带的卷积运算:filter2D 前言 数字图像处理c+ ...

  3. Opencv3编程入门学习笔记(三)之访问图像像素的三种方法

    访问图像像素的三种方法:指针访问,迭代器访问,动态地址访问.访问最快的为指针访问,以下算法在几毫秒,但指针访问容易造成内存泄漏:其次为迭代器访问:最后为动态地址访问. 以下程序是根据<OpenC ...

  4. opencv2.4.3通过不同方式访问图像像素

    通过不同方式访问图像像素 最近在学习vs2010并结合opencv2.4.3进行图像处理,首先研究了在opencv中如何去访问像素,查阅资料,浏览博客,总结了一下,一般有三种方法:Mat类的.at() ...

  5. ITK系列4_ ITK访问图像像素数据

    实例4 ITK访问图像像素数据 #include "itkImage.h" //这个例子阐述了 SetPixel( )和 GetPixel( )方法的用法 //可以直接访问图像中包 ...

  6. opencv中求图像像素值中位数

    话不多说,直接上源码: int GetMidValue(Mat& input) {int rows = input.rows;int cols = input.cols;float histo ...

  7. 【OpenCV】简单高效地访问图像像素

    对于单通道字节型图像: IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); int height = img->heig ...

  8. opencv(二)图像像素提取及操作

    为了编写计算机视觉应用,我们必须会存取图像的内容,如修改或者创建图像,这些过程都需要对图像的基本元素进行操作,即所谓的像素. 1[存取像素值] 为了存取矩阵元素,我们需要在代码中指定元素所在的行和列, ...

  9. 【OpenCV 4】图像像素的归一化

    一.编程环境: OpenCV  4.1.0 IDE Visual Studio 2017 Enterprise (15.9.13) 操作系统 Windows 10 x64 中文专业版 (1903) 二 ...

最新文章

  1. ●洛谷P3168 [CQOI2015]任务查询系统
  2. Objective-C语言中对象相等性与指针相等分析。
  3. Java序列化和反序列化小记
  4. DevExpress控件安装和初次使用图解
  5. 关于 early Z 与 z-prepass
  6. 方法的重写-覆盖父类方法,重写子类方法实现
  7. Learning Face Age Progression: A Pyramid Architecture of GANs
  8. web视图层:JSP
  9. Android录音并输出为Mp4文件
  10. 一加9系列曝光:骁龙875旗舰芯片加持 可能存在超过四种机型
  11. linux环境下如何查看solr版本,Solr环境搭建(linux)
  12. scala 构造_Scala咖喱和自动类型依赖的封闭构造
  13. 济安横断面为什么会有水印_PS差值模式是如何去水印的?你看的懂抖音的沙雕做法?...
  14. Day003 20210208
  15. 尼康数码相机照片数据恢复怎么办
  16. c#中panel控件有什么作用
  17. 10个免费高清图片网站,良心推荐,收藏就是学会了
  18. HTML5期末大作业:美食坊网站设计——美食坊美食购物主题(15页) HTML+CSS+JavaScript
  19. Spark+Scala:数据分析统计
  20. WIN11安装子系统

热门文章

  1. Docker-Compose快速搭建Oracle-11G系统
  2. Spring Restful Web服务示例 - 使用JSON,Jackson和客户端程序
  3. MySQL 处理重复数据
  4. 熊猫多模式站群-开发日志
  5. 在CentOS7上安装RocketMQ 4.8.0
  6. 【C语言】输入三个正整数a,b,c,求最大值,要求定义一个计算最大值的函数max(a,b),返回a,b的值...
  7. 【C语言】输入一个字符串,并对字符串中的偶数位置的字符按从小到大的顺序排序,奇数位置的字符不动,输出排序后的结果...
  8. C#LeetCode刷题之#404-左叶子之和​​​​​​​​​​​​​​(Sum of Left Leaves)
  9. f2fs 设置stripe_欧洲如何在PSD2下使用Stripe实现3DS2的SCA合规性
  10. 网络服务器租赁费用_如何分析租赁季节性和趋势以节省租赁费用