本文为原创,若有错误欢迎批评指正!

一. IplImage结构体构成

IplImage比CvMat要复杂一些,结构体组成如下:

typedef struct _IplImage
{ int nSize;    /* IplImage大小 */int ID;    /* 版本 (=0)*/int nChannels;  /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */ int alphaChannel;  /* 被OpenCV忽略 */ int depth;   /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */ char colorModel[4]; /* 被OpenCV忽略 */ char channelSeq[4]; /* 被OpenCV忽略 */ int dataOrder;      /* 0 - 交叉存取颜色通道, 意思是在每一行的结构都是BGRBGRBGR...1 - 分开的颜色通道,把几个颜色通道分为几个颜色平面存储cvCreateImage只能创建交叉存取图像 */ int origin;     /* 0 - 顶—左结构,1 - 底—左结构 (Windows bitmaps 风格) */ int align;     /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */ int width;     /* 图像宽像素数 */ int height;    /* 图像高像素数*/ struct _IplROI *roi;  /* 图像感兴趣区域. 当该值非空只对该区域进行处理 */ struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */ void *imageId;  /* 同上*/ struct _IplTileInfo *tileInfo;  /*同上*/ int imageSize;    /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/ char *imageData;    /* 指向排列的图像数据 */ int widthStep;     /* 排列的图像行大小,以字节为单位 */ int BorderMode[4];     /* 边际结束模式, 被OpenCV忽略 */ int BorderConst[4];    /* 同上 */ char *imageDataOrigin;    /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
} IplImage;

这里比较重要的参数是height、width、depth和nChannels。

二. 访问图像数据

与CvMat类似,都有三种方法。

首先是函数的方法:

/*函数的方法*/
IplImage* img=cvLoadImage(filename);
CvScalar s;       /*sizeof(s) == img->nChannels*/
s=cvGet2D(img,i,j);  /*get the (i,j) pixel value*/
cvSet2D(img,i,j,s);   /*set the (i,j) pixel value*/

采用宏的方法:

/*宏*/
IplImage* img; //malloc memory by cvLoadImage or cvCreateImage
for(int row = 0; row < img->height; row++)
{for (int col = 0; col < img->width; col++){b = CV_IMAGE_ELEM(img, UCHAR, row, col * img->nChannels + 0); g = CV_IMAGE_ELEM(img, UCHAR, row, col * img->nChannels + 1); r = CV_IMAGE_ELEM(img, UCHAR, row, col * img->nChannels + 2);}
}

接下来是最推崇的使用指针的方法。在这之前要弄清楚IplImage与Cvmat的一些差别,剩下的用法类似。IplImage在计算行地址的时候也要采用行长度widthStep而不是图像的宽度,与CvMat中step类似。IplImage图像的首地址记作imageData,与CvMat中data类似。IplImage访问时指针设置为(uchar*),而CvMat中data为联合类型,必须说明使用的指针类型。

/*指针访问*/
IplImage* img; //malloc memory by cvLoadImage or cvCreateImage
uchar b, g, r; // 3 channels
for(int row = 0; row < img->height; row++)
{for (int col = 0; col < img->width; col++){b = ((uchar *)(img->imageData + row * img->widthStep))[col * img->nChannels + 0]; g = ((uchar *)(img->imageData + row * img->widthStep))[col * img->nChannels + 1]; r = ((uchar *)(img->imageData + row * img->widthStep))[col * img->nChannels + 2];}
}

三. 一个比较综合的应用

这里定义一个稍微复杂一点的应用,包括了对图像的常用操作,基本上足够用来实现其他的图像算法了。

首先读入一幅图像,若为3通道的则转化为一通道,然后将图像右下角1/4置为白色。

#include <opencv2\opencv.hpp>  int main()
{IplImage *img = cvLoadImage("D:\\_Gonzalez\\ch02\\Fig0205(a)(cktboard_200dpi).tif");//获取图像的参数  printf("width=%d\n", img->width);printf("height=%d\n", img->height);printf("channel=%d\n", img->nChannels);if (img->nChannels == 3){//新建一个与img一样大的一通道空图像  IplImage *dst = cvCreateImage(cvSize(img->width, img->height), img->depth, 1);//将彩色图像转化为一通道灰度图  cvCvtColor(img, dst, CV_RGB2GRAY);img = dst;}for (int y = img->height / 2; y < img->height; y++){uchar* ptr = (uchar*)(img->imageData + y*img->widthStep);for (int x = img->width / 2; x < img->width; x++){ptr[x + 1] = 255;ptr[x + 2] = 255;ptr[x + 3] = 255;}}cvNamedWindow("example", CV_WINDOW_AUTOSIZE);cvShowImage("example", img);cvWaitKey(0);cvReleaseImage(&img);cvDestroyWindow("example");
}

如果将要求改为将三通道的img右下角1/4置为白色,相应操作变成:

for (int y = img->height / 2; y < img->height; y++)
{uchar* ptr = (uchar*)(img->imageData + y*img->widthStep);for (int x = img->width / 2; x < img->width; x++){ptr[x + 1] = 255;ptr[x + 2] = 255;ptr[x + 3] = 255;/*也可以是*(ptr+3*x+1) = 255;*(ptr+3*x+2) = 255;*(ptr+3*x+2) = 255;*/}
}

转载于:https://www.cnblogs.com/jenny1000000/p/7738334.html

OpenCV中的三种图像数据结构CvMat, IplImage和Mat(二)IplImage相关推荐

  1. OpenCV计算机视觉编程之三种图像像素的遍历方法

    为了构建计算机视觉应用程序,需要学会访问图像内容,有时也要修改或创建图像,如何操作图像的像素,就需要遍历一幅图像并处理每一个像素.现在我们就来介绍OpenCV三种图像像素的遍历方法: 一. 用cv:: ...

  2. ROS学习:cv_bridge与opencv版本冲突三种解决方案

    cv_bridge与opencv版本冲突三种解决方案 1 问题描述: 2 解决方案: 2.1 不使用cv_bridge包 2.2 令cv_bridge使用opencv版本切换为自己工程所使用的版本 2 ...

  3. OpenCV中的几种角点检测方法

    1.Harris角点检测 import numpy as np import cv2 as cv import matplotlib.pyplot as pltplt.rcParams['font.s ...

  4. 范数介绍及C++/OpenCV/Eigen的三种实现

    有时我们需要衡量一个向量的大小.在机器学习中,我们经常使用被称为范数(norm)的函数衡量向量大小.形式上,Lp范数定义如下: 范数(包括Lp范数)是将向量映射到非负值的函数.直观上来说,向量x的范数 ...

  5. 硬核资源!Redis 五种数据结构以及三种高级数据结构解析(详解)

    上一篇分享的是<深入理解JVM>,这篇给大家分享<Redis 五种数据结构以及三种高级数据结构解析>. 前言 在 Redis 最重要最基础就属 它丰富的数据结构了,Redis ...

  6. 三种图像内插法(最近邻内插法、双线性内插法、双三次内插法)的做法 代码实现

    参考博客 数字图像处理学习笔记(四)--数字图像的内插.度量.表示与质量_闭关修炼--暂退的博客-CSDN博客 数字图像处理学习笔记(七)--用Pycharm及MATLAB实现三种图像内插法(最近邻内 ...

  7. OpenCV中的5种平滑滤波操作

    平滑滤波是一种简单又常见的图像处理操作.平滑图像的目的有很多,但通常都是为了减少噪声和伪影. 在OpenCV中共有5种平滑滤波操作,分别是以下几种: 实验测试代码如下: #include<ios ...

  8. css中的三种基本定位机制

    css中的三种基本定位机制 a.普通文档流 b.定位:相对定位 绝对定位 固定定位 c.浮动 1.普通流中,元素位置由文档顺序和元素性质决定,块级元素从上到下依次排列,框之间的垂直距离由框的垂直mar ...

  9. Oracle的join默认为,Oracle中的三种Join方法详解

    这里将为大家介绍Oracle中的三种Join方法,Nested loop join.Sort merge join和Hash join.整理出来以便帮助大家学习. 基本概念 Nested loop j ...

最新文章

  1. Java内存溢出详解之Tomcat配置
  2. class 与 原型链 解析
  3. 事件溯源|日志记录-一个基础的微服务模式
  4. 安装smac的注意事项
  5. ActiveMQ 持久化讯息数据库信息
  6. python执行gradle脚本
  7. 领域应用 | 2020 年中国知识图谱行业分析报告
  8. sqlserver服务启动失败_条码打印软件连接SQL数据库出现TCP连接失败解决办法
  9. react native一键分享功能实现amp;原理和注意点(支持微信、qq、新浪微博等)
  10. 区块链与分享型数据库
  11. lambda表达式 java 效率_Java8新特性效率之Lambda
  12. 网页结构的简介和Xpath语法的入门教程
  13. Caused by: java.lang.NoClassDefFoundError: net/sf/ezmorph/Morpher
  14. [转]SQL事务回滚的问题及其解决的方法
  15. 一个非常标准的Java连接Oracle数据库的示例代码
  16. 什么样的 python 可以可谓专业 PyPI 项目?刚刚学到三个概念:pep8、Sphinx、pytest与GitHub Action的集成
  17. 【数据结构笔记44】线性探测的散列表的逆问题(拓扑排序的方法)
  18. NDK配置文件Android.mk简介
  19. UnsupportedOperationException:can‘t convert to dimension :typx=0x1
  20. 一点一滴开始搭建自己的项目框架之支付宝篇 支付宝提现

热门文章

  1. 【转载】Scarbee Pre-Bass 贝司的使用教程
  2. Mysql配置参数常见问题
  3. .net source code download
  4. ORACLE SQLSERVER2005分页
  5. 查询成绩最好的前两名_官宣!CPA考试成绩查询时间+合格标准+查询入口+成绩复核!注会考生查分前不看亏大了...
  6. C语言考试题及答案(8),2015年计算机二级C语言测试题及答案(8)
  7. 济宁医学院计算机科学与技术专业怎么样,济宁医学院专业排名及介绍 哪些专业最好...
  8. Java虚拟机(三)——类加载子系统概述
  9. bom实现方块移动_html5实现简单的拼图小游戏
  10. 无法解析 uafxcw.lib_吉利DMS系统一周热点问题解析