IplImage简介
结构定义:
typedef struct _IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /* Ignored by OpenCV */
int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
char colorModel[4]; /* Ignored by OpenCV */
char channelSeq[4]; /* ditto */
int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels.
cvCreateImage can only create interleaved images */
int origin; /* 0 - top-left origin,
1 - bottom-left origin (Windows bitmaps style). */
int align; /* Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead. */
int width; /* Image width in pixels. */
int height; /* Image height in pixels. */
struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */
struct _IplImage *maskROI; /* Must be NULL. */
void *imageId; /* " " */
struct _IplTileInfo *tileInfo; /* " " */
int imageSize; /* Image data size in bytes
(==image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /* Pointer to aligned image data. */
int widthStep; /* Size of aligned image row in bytes. */
int BorderMode[4]; /* Ignored by OpenCV. */
int BorderConst[4]; /* Ditto. */
char *imageDataOrigin; /* Pointer to very origin of image data
(not necessarily aligned) -
needed for correct deallocation */
}
IplImage;
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]; /* 同上 */
int dataOrder; /* 0 - 交叉存取颜色通道, 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;
The IplImage is taken from the Intel Image Processing Library, in which the format is native. OpenCV only supports a subset of possibleIplImage formats, as outlined in the parameter list above.
In addition to the above restrictions, OpenCV handles ROIs differently. OpenCV functions require that the image size or ROI size of all source and destination images match exactly. On the other hand, the Intel Image Processing Library processes the area of intersection between the source and destination images (or ROIs), allowing them to vary independently.
Member Function Documentation
| inline |
IplImage::_IplImage | ( | const cv::Mat & | m | ) |
Member Data Documentation
int IplImage::align |
Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead.
int IplImage::alphaChannel |
Ignored by OpenCV
int IplImage::BorderConst[4] |
Ditto.
int IplImage::BorderMode[4] |
Ignored by OpenCV.
char IplImage::channelSeq[4] |
ditto
char IplImage::colorModel[4] |
Ignored by OpenCV
int IplImage::dataOrder |
0 - interleaved color channels, 1 - separate color channels. cvCreateImage can only create interleaved images
int IplImage::depth |
Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported.
int IplImage::height |
Image height in pixels.
int IplImage::ID |
version (=0)
char* IplImage::imageData |
Pointer to aligned image data.
char* IplImage::imageDataOrigin |
Pointer to very origin of image data (not necessarily aligned) - needed for correct deallocation
void* IplImage::imageId |
" "
int IplImage::imageSize |
Image data size in bytes (==image->height*image->widthStep in case of interleaved data)
struct _IplImage* IplImage::maskROI |
Must be NULL.
int IplImage::nChannels |
Most of OpenCV functions support 1,2,3 or 4 channels
int IplImage::nSize |
sizeof(IplImage)
int IplImage::origin |
0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style).
struct _IplROI* IplImage::roi |
Image ROI. If NULL, the whole image is selected.
struct _IplTileInfo* IplImage::tileInfo |
" "
int IplImage::width |
Image width in pixels.
int IplImage::widthStep |
Size of aligned image row in bytes.
数据的访问存取
下面看一个图像数据存取的例子:
例子转自:http://blog.csdn.net/to_utopia/article/details/4856171
1.直接存取: (效率高, 但容易出错)
- 对单通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); ((uchar *)(img->imageData + i*img->widthStep))[j]=111;
- 对多通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
- 对多通道浮点图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
2.用指针直接存取 : (在某些情况下简单高效)
-
对单通道字节图像:
IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
int height = img->height;
int width = img->width;
int step = img->widthStep/sizeof(uchar);
uchar* data = (uchar *)img->imageData;
data[i*step+j] = 111;
- 对多通道字节图像:
IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
int height = img->height;
int width = img->width;
int step = img->widthStep/sizeof(uchar);
int channels = img->nChannels;
uchar* data = (uchar *)img->imageData;
data[i*step+j*channels+k] = 111;
- 对多通道浮点图像(假设用4字节调整):
IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
int height = img->height;
int width = img->width;
int step = img->widthStep/sizeof(float);
int channels = img->nChannels;
float * data = (float *)img->imageData;
data[i*step+j*channels+k] = 111;
3.使用 c++ wrapper 进行直接存取: (简单高效)
- 对单/多通道字节图像,多通道浮点图像定义一个 c++ wrapper:
template<class T> class Image { private: IplImage* imgp; public: Image(IplImage* img=0) {imgp=img;} ~Image(){imgp=0;} void operator=(IplImage* img) {imgp=img;} inline T* operator[](const int rowIndx) { return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));} }; typedef struct{ unsigned char b,g,r; } RgbPixel; typedef struct{ float b,g,r; } RgbPixelFloat; typedef Image<RgbPixel> RgbImage; typedef Image<RgbPixelFloat> RgbImageFloat; typedef Image<unsigned char> BwImage; typedef Image<float> BwImageFloat;
- 单通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); BwImage imgA(img); imgA[i][j] = 111;
- 多通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); RgbImage imgA(img); imgA[i][j].b = 111; imgA[i][j].g = 111; imgA[i][j].r = 111;
- 多通道浮点图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); RgbImageFloat imgA(img); imgA[i][j].b = 111; imgA[i][j].g = 111;imgA[i][j].r = 111;
其他示例:
直接访问:
对我们来说比较重要的两个元素是:char *imageData以及widthStep。imageData存放图像像素数据,而widStep类似CvMat中的step,表示以字节为单位的行数据长度。
一个m*n的单通道字节型图像,其imageData排列如下:
如果我们要遍历图像中的元素,只需:
- IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
- uchar* tmp;
- for(int i=0;i<img->height;i++)
- for(int j=0;j<img->width;j++)
- *tmp=((uchar *)(img->imageData + i*img->widthStep))[j];
这种直接访问的方法速度快,但容易出错,我们可以通过定义指针来访问。即:
- IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
- ucha* data=(uchar *)img->imageData;
- int step = img->widthStep/sizeof(uchar);
- uchar* tmp;
- for(int i=0;i<img->height;i++)
- for(int j=0;j<img->width;j++)
- *tmp=data[i*step+j];
而多通道(三通道)字节图像中,imageData排列如下:
其中(Bi,Bj)(Gi,Gj)(Ri,Rj)表示图像(i,j)处BGR分量的值。使用指针的遍历方法如下:
- IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
- IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
- uchar* data=(uchar *)img->imageData;
- int step = img->widthStep/sizeof(uchar);
- int channels = img->nChannels;
- uchar *b,*g,*r;
- for(int i=0;i<img->height;i++)
- for(int j=0;j<img->width;j++){
- *b=data[i*step+j*chanels+0];
- *g=data[i*step+j*chanels+1];
- *r=data[i*step+j*chanels+2];
- }
*如果要修改某像素值,则直接赋值。
使用cvGet2D()函数访问:
- CvScalar cvGet1D( const CvArr* arr, int idx0 );
- CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );
- CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
- CvScalar cvGetND( const CvArr* arr, int* idx );
- IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
- double tmp;
- for(int i=0;i<img->height;i++)
- for(int j=0;j<img->width;j++)
- tmp=cvGet2D(img,i,j).val[0];
- IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
- double tmpb,tmpg,bmpr;
- for(int i=0;i<img->height;i++)
- for(int j=0;j<img->width;j++){
- tmpb=cvGet2D(img,i,j).val[0];
- tmpg=cvGet2D(img,i,j).val[1];
- tmpr=cvGet2D(img,i,j).val[2];
- }
- void cvSet1D( CvArr* arr, int idx0, CvScalar value );
- void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );
- void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );
- void cvSetND( CvArr* arr, int* idx, CvScalar value );
参考文档
http://blog.csdn.net/xiaowei_cqu/article/details/7557063#