OpenCV视觉库
VS2010编译器
IplImage数据结构:来自于 Intel Image Processing Library。OpenCV 只支持其中的一个子集:IplImage图像头:typedef struct _IplImage ....{ int nSize; /* IplImage大小,=sizeof(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 - 交叉存取颜色通道,对三通道RGB图像,像素存......................................../*储顺序为BGR BGR BGR ... BGR;......................................../*1 - 分开的颜色通道,对三通道RGB图像,像素存储顺......................................../*序为RRR...R GGG...G BBB...B。......................................./*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;
在IplImage数据类型中,访问图像像素最重要的元素:....char *imageData; /* 指向排列的图像数据 */....int widthStep;/*排列的图像行大小,以字节为单位*/或....int width;/*图像宽像素数*/一个m*n的单通道字节型图像,其imageData排列如作图:多通道(三通道)字节图像中,imageData排列如右图:
访问图像像素方法:(1)根据上述数据排列,定义指针访问:语句:..........pData=(unsigned char*)(pImg->imageData+i*pImg->widthStep)[j];//像素点的地址其中,pImg->imageData:指向图像pImg第一行首地址;widthStep:图像的行宽,单位字节;unsigned char*:由于pImg->imageData默认为char类型,图像像素值中有可能出现负数,所以需要强制类型转换为unsigned char;对于单通道图像;【注】:先遍历行和先遍历列的区分;如下图:
(2)对于多通道图像;IplImage* img=cvCreateImage(cvGetSize (_pImg),IPL_DEPTH_8U,3); unsigned char* data=(unsigned char *)img->imageData; int step = img->widthStep/sizeof(uchar); int channels = img->nChannels; uchar *b,*g,*r; for(int i=0;i
注意事项:①OpenCV中使用imread()、cvLoadImage()得到的图像,其数据类型都是char类型;②对于32为操作系统,内存存储图像数据满足每行数据4字节对齐;即:当图像为单通道char/uchar,每行数据大小为sizeof(uchar)*width=widthStep字节;如果width为4的倍数,那么widthStep=width;如果width不为4的倍数,则需补齐4个字节。eg. width=16àwidthStep=16字节;.......width=18àwidthStep=(width+2)/4*4=20字节;当图像为3通道float型,widthStep=(width*3*sizeof(float)+3)/4*4;widthStep只和宽度与数据类型有关。③示例:创建一副宽*高为111*113大小的3通道float类型图像,访问第31行、51列的图像数据。IplImage *image=cvCreateImage(cvSize(111,113),IPL_DEPTH_32F,3);//则widthStep=(111*3*sizeof(float)+3)/4*4=2664字节;float *data_1=(float*)image->imageData;float val_1=*(data_1+31*width+51);//或char *data_2=image->imageData;float val_2=*(float*)(data_2+31*image->widthStep+51*sizeof(float));④【注】:对于char、uchar图像数据类型,用widthStep;对于float、double图像数据类型,用width;否则会出错。
【特别注意】:在IplImage头中,imageData默认为char*类型;当 .IplImage* img=cvCreateImage(cvGetSize(_Img),IPL_DEPTH_8U,1)......unsigned char *data_1;......for(int i=0;i
对于char、uchar图像数据类型,用widthStep;
对于float、double图像数据类型,用width;
widthStep=(width*3*sizeof(float)+3)/4*4;