IplImage数据结构
IplImage |-- int nChannels; // 颜色通道数目 (1,2,3,4) |-- int depth; // 像素的位深: | // IPL_DEPTH_8U, IPL_DEPTH_8S, | // IPL_DEPTH_16U,IPL_DEPTH_16S, | // IPL_DEPTH_32S,IPL_DEPTH_32F, | // IPL_DEPTH_64F |-- int width; // 图像宽度(像素为单位) |-- int height; // 图像高度 |-- char* imageData; // 图像数据指针 | // 注意彩色图像按BGR顺序存储数据 |-- int dataOrder; // 0 - 将像素点不同通道的值交错排在一起,形成单一像素平面 | // 1 - 把所有像素同通道值排在一起,形成若干个通道平面,再把平面排列起来 | // cvCreateImage 只能创建像素交错排列式的图像 |-- int origin; // 0 – 像素原点为左上角, | // 1 – 像素原点为左下角 (Windows bitmaps style) |-- int widthStep; // 相邻行的同列点之间的字节数 width * nChannels * depth / 8 |-- int imageSize; // 图像的大小(字节为单位) = height*widthStep |-- struct _IplROI *roi;// 图像的感兴趣区域(ROI). ROI非空时对图像的 | // 处理仅限于ROI区域. |-- char *imageDataOrigin; // 图像数据未对齐时的数据原点指针 | // (需要正确地重新分配图像内存 ) | // (needed for correct image deallocation) |-- int align; // 图像数据的行对齐: 4 or 8 byte alignment | // OpenCV 中无此项,采用widthStep代替 |-- char colorModel[4]; // 颜色模型 – OpenCV中忽略此项点击打开链接 http://wiki.opencv.org.cn/index.php/Cxcore%E5%9F%BA%E7%A1%80%E7%BB%93%E6%9E%84#IplImage
IplImage 是CvMat的子类,CvMat是OpenCV的矩阵结构,其定义为,
CvMat
多通道矩阵
typedef struct CvMat { int type; /* CvMat 标识 (CV_MAT_MAGIC_VAL), 元素类型和标记 */ int step; /* 以字节为单位的行数据长度*/ int* refcount; /* 数据引用计数 */ union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; /* data 指针 */ #ifdef __cplusplus union { int rows; int height; }; union { int cols; int width; }; #else int rows; /* 行数 */ int cols; /* 列数*/ #endif } CvMat;
IplImage从本质上将是一个CvMat对象,但是它还有一些成员变量将矩阵解释为图像。
ROI 是IplImage结构体重的重要参数,用于对图像中的一部分进行操作,其中
cvSetImageROI()用于设置ROI区域 cvResetImageROI()用于取消ROI
其函数形式为:
void cvSetImageROI( IplImage* image, CvRect rect );
void cvResetImageROI( IplImage* image );
1. 用imageROI改变某范围的像素
调用函数:
doROIdemo(img,150,150,300,300,150);
结果:

在上面的函数中,用到了cvRect等结构体,对这些结构体说明:
/*
对图像中感兴趣的部分的处理
*/
#include "highgui.h"
#include "cv.h"
void doROIdemo(IplImage* img, int x, int y, int width, int height,int add)
{
cvSetImageROI(img, cvRect(x,y,width,height));
cvAddS(img,cvScalar(add),img);
cvNamedWindow("roi_add",1);
cvShowImage("roi_add",img);
cvWaitKey(0);
}
结果:
2. 用widthStep实现
有些时候在处理的过程中,想在操作过程中设置和保持一幅图像的多个子区域处于活动状态,但是ROI只能串行处理并且必须不断设置和重置。
用widthStep处理的具体方法如下:
1.创建一个图像头,让其width和height的值等于interest_rect的width和height的值。
2.按interest_img的起点设置图像起点(左上角或者左下角)。
3.设置子图像的widthStep与较大的interest_img相同。
4.这样即可在子图像中逐行地步进到大图像里子区域中下一行开始处的合适位置。
5.最后设置子图像的imageData指针指向兴趣子区域的开始。
void doROIdemo(IplImage* img, int x, int y, int width, int height,int add)
{
CvRect interest_rect = cvRect(x,y,width,height);
IplImage* sub_img = cvCreateImageHeader(
cvSize(
interest_rect.width,
interest_rect.height
),
img->depth,
img->nChannels
);
sub_img->origin = img->origin;
sub_img->widthStep = img->widthStep;
sub_img->imageData = img->imageData
+ interest_rect.x * img->widthStep
+ interest_rect.y * img->nChannels;
cvAddS(sub_img,cvScalar(150),sub_img);
cvNamedWindow("roi_add",1);
cvShowImage("roi_add",sub_img);
cvWaitKey(0);
cvReleaseImageHeader(&sub_img);
}
在上面的函数中,用到了cvRect等结构体,对这些结构体说明:
CvRect
矩形框的偏移和大小
typedef struct CvRect { int x; /* 方形的最左角的x-坐标 */ int y; /* 方形的最上或者最下角的y-坐标 */ int width; /* 宽 */ int height; /* 高 */ } CvRect;
/* 构造函数*/ inline CvRect cvRect( int x, int y, int width, int height ); { CvRect os; os.x = x; os.y = y; os.width = width; os.height = heigth; reture os; }
CvSize
矩形框大小,以像素为精度
typedef struct CvSize { int width; /* 矩形宽 */ int height; /* 矩形高 */ } CvSize;
/* 构造函数 */ inline CvSize cvSize( int width, int height );
注意:构造函数的cv是小写!
CvScalar
可存放在1-,2-,3-,4-TUPLE类型的捆绑数据的容器
typedef struct CvScalar { double val[4] } CvScalar;
/* 构造函数:用val0初始化val[0]用val1初始化val[1], 以此类推*/ inline CvScalar cvScalar( double val0, double val1, double val2, double val3); { CvScalar arr; arr.val[4] = {val0,val1,val2,val3}; reture arr;}
/* 构造函数:用val0123初始化所有val[0]...val[3] */ inline CvScalar cvScalarAll( double val0123 ); { CvScalar arr; arr.val[4] = {val0123,val0123,val0123,val0123,}; reture arr;}
/* 构造函数:用val0初始化val[0],用0初始化val[1],val[2],val[3] */ inline CvScalar cvRealScalar( double val0 ); { CvScalar arr; arr.val[4] = {val0}; reture arr;}
CvPoint
二维坐标系下的点,类型为整型
typedef struct CvPoint { int x; /* X坐标, 通常以0为基点 */ int y; /* y坐标, 通常以0为基点 */ } CvPoint;
/* 构造函数 */ inline CvPoint cvPoint( int x, int y );
/* 从 CvPoint2D32f类型转换得来 */ inline CvPoint cvPointFrom32f( CvPoint2D32f point )
http://wiki.opencv.org.cn/index.php/Cxcore%E5%9F%BA%E7%A1%80%E7%BB%93%E6%9E%84#IplImage