opencv学习_5 (IplImage的结构)

本文详细解析IplImage结构体的各项属性,并通过实例演示如何访问图像数据、分解彩色图像通道及利用ROI实现图像替换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IplImage结构体为:

[cpp]  view plain  copy
 print ?
  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:重要的参数有nChannels  depth  origin width height  widthStep<和矩阵的step相同>  imageData—指针<注意图像的数据类型为ucharimageDatachar类型,没有CvMat那么复杂了>

2:彩色图像的数据排列方式

彩色图像有三个通道(B,G,R),这三个通道的值,在Opencv中的排列顺序是B0G0R0B1G1R1…BnGnRn,采用这种交叉排列的方式进行存储。

3:访问IplImage的数据 ---- 指针访问<注意图像的数据类型为uchar >

代码:

[cpp]  view plain  copy
 print ?
  1. #include <iostream>  
  2. #include "cv.h"  
  3. #include "cxcore.h"  
  4. #include "highgui.h"  
  5. using namespace std;  
  6. int main()  
  7. {  
  8.                 IplImage *image = cvLoadImage("F:\\11.jpg",1);  
  9.                 cvNamedWindow("show",0);  
  10.                 for(int y = 0; y < image->height; y++)  
  11.                 {  
  12.                     uchar *p_image = (uchar*)(image->imageData + y * image->widthStep);  
  13.                     for(int x = 0; x < image->width; x++)  
  14.                     {  
  15.                         *(p_image + x*3) = 0;  
  16.                     }  
  17.                 }  
  18.                 cvShowImage("show", image);  
  19.                 cvWaitKey(0);  
  20.                 return 0;     
  21. }  

4:将三通道分解为三个单通道     彩色必须由三种颜色构成 单通道只能说明是该取值,不能说明其它色彩,彩色必须要有三种通道构成   用到的函数为cvCreateImage

code:

[cpp]  view plain  copy
 print ?
  1. #include <iostream>  
  2. #include "cv.h"  
  3. #include "cxcore.h"  
  4. #include "highgui.h"  
  5. using namespace std;  
  6. int main()  
  7. {  
  8.     IplImage *image = cvLoadImage("F:\\11.jpg",1);  
  9.     IplImage *b_img = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);  
  10.     IplImage *g_img = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);  
  11.     IplImage *r_img = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);  
  12.     cvNamedWindow("show",0);  
  13.     cvNamedWindow("b",0);  
  14.     cvNamedWindow("g",0);  
  15.     cvNamedWindow("r",0);  
  16.     for(int y = 0; y < image->height; y++)  
  17.     {  
  18.         uchar *p_image = (uchar*)(image->imageData + y * image->widthStep);  
  19.         uchar *b_image = (uchar*)(b_img->imageData + y * b_img->widthStep);  
  20.         uchar *g_image = (uchar*)(g_img->imageData + y * g_img->widthStep);  
  21.         uchar *r_image = (uchar*)(r_img->imageData + y * r_img->widthStep);  
  22.         for(int x = 0; x < image->width; x++)  
  23.         {  
  24.             b_image[x] = *(p_image + x*3);  
  25.             g_image[x] = *(p_image + x*3 + 1);  
  26.             r_image[x] = *(p_image + x*3 + 2);  
  27.         }  
  28.     }  
  29.     cvShowImage("show", image);  
  30.     cvShowImage("b", b_img);  
  31.     cvShowImage("g", g_img);  
  32.     cvShowImage("r", r_img);  
  33.     cvWaitKey(0);  
  34.     cvReleaseImage(&image);  
  35.     cvReleaseImage(&b_img);  
  36.     cvReleaseImage(&g_img);  
  37.     cvReleaseImage(&r_img);  
  38.     cvDestroyWindow("show");  
  39.     cvDestroyWindow("b");  
  40.     cvDestroyWindow("g");  
  41.     cvDestroyWindow("r");  
  42.     return 0;     
  43. }  

5:ROI和COI的理解

ROI是Region of Interest 的缩写。表示的是在一副大图像的感兴趣区域。”感兴趣区域”,指的是再一副大图像中,我们需要做处理的一部分

  COI是Channels Of Interest, 是指感兴趣的通道,彩色图像有BGR三个通道。所以,可以选择其中一个作为感兴趣通道

用到的函数为cvSetImageROI  cvResetImageROI cvCopy

  code(图像的一部分替换另一幅图像的一部分):

[cpp]  view plain  copy
 print ?
  1. #include <iostream>  
  2. #include "cv.h"  
  3. #include "cxcore.h"  
  4. #include "highgui.h"  
  5. using namespace std;  
  6.   
  7. int main()  
  8. {  
  9.     IplImage *tongtong = cvLoadImage("F:\\tongtong.jpg",1);  
  10.     IplImage *jiale = cvLoadImage("F:\\jiale.jpg",1);  
  11.     CvRect rect,rect1;  
  12.     rect.x = 1200;  
  13.     rect.y = 300;  
  14.     rect.width = 340;  
  15.     rect.height = 400;  
  16.     rect1.x = 90;  
  17.     rect1.y= 65;  
  18.     rect1.width = 120;  
  19.     rect1.height = 150;  
  20.     cvSetImageROI(jiale,rect);  
  21.     cvSetImageROI(tongtong,rect1);  
  22.     cvResize(jiale,tongtong);  
  23.     //cvCopy(jiale,tongtong);  
  24.     cvResetImageROI(tongtong);  
  25.     cvNamedWindow("tongtong");  
  26.     cvNamedWindow("jiale");  
  27.     cvShowImage("tongtong",tongtong);  
  28.     cvShowImage("jiale",jiale);  
  29.     cvWaitKey(0);  
  30.     return 0;  
  31. }  


作者:小村长  出处:http://blog.youkuaiyun.com/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值