《学习opencv》笔记——IplImage数据结构

1.IplImage数据结构

(1)IplImage的结构

typedef struct _IplImage
{
    int nSize;    //IplImage大小
    int ID; 		//ID
    int nChannels;  //通道数,大多数OPENCV函数支持1,2,3 或 4 个通道。
    int alphaChannel;
    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];
    char channelSeq[4];
    int dataOrder;     //颜色通道排列规则 0 - 交叉存取颜色通道, 1 - 分开的颜色通道.cvCreateImage只能创建交叉存取图像
    int origin; // 坐标原点位置,0 - 顶—左结构,1 - 底—左结构 (Windows bitmaps 风格)
    int align;
    int width; //图像宽像素数
    int height; //图像高像素数
    struct _IplROI *roi;// 图像感兴趣区域. 当该值非空只对该区域进行处理
    struct _IplImage *maskROI; // 在 OpenCV中必须置NULL
    void *imageId; // 在 OpenCV中必须置NULL
    struct _IplTileInfo *tileInfo; // 在 OpenCV中必须置NULL
    int imageSize; // 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节
    char *imageData; // 指向排列的图像数据
    int widthStep; //排列的图像行大小,以字节为单位
    int BorderMode[4]; //边际结束模式//
    int BorderConst[4];
    char *imageDataOrigin; // 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的
}
IplImage;

(2)访问数据图像

imageData里存放的是HSV空间数据,所以下面的程序是将S和V部分加满。

#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
	IplImage* img = cvLoadImage("460.jpg");
	void saturate_sv(IplImage *img);
	saturate_sv(img);
	cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
	cvShowImage("Example1", img );
	cvWaitKey(0);
	cvReleaseImage( &img );
	cvDestroyWindow("Example1");
	return 0;
}

void saturate_sv(IplImage *img)
{
	for(int y = 0;y<img->height;y++){
		uchar* ptr = (uchar*)(
			img->imageData + y * img->widthStep
		);
		for(int x = 0;x < img->width;x++)
		{
		ptr[3*x+1] = 255;
		ptr[3*x+2] = 255;
		}
	}
}

加满S和V后的结果为

(3)对ROI和widthStep的补充

ROI和widthStep在实际工作中有很重要的作用,在很多情况下,使用它们会提高计算机视觉代码的执行速度。这是因为它们运行对图像的某一小部分进行操作,而不是对整个图像进行运算。

实例代码,利用imageROI来增加某范围的像素

#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{

	IplImage* src;
	if( ((src=cvLoadImage("460.jpg")) != 0 ))
	{
		int x = atoi("80");
		int y = atoi("150");
		int width = atoi("270");
		int height = atoi("250");
		int add = atoi("-100");
		cvShowImage( "大脸猫", src);
		cvSetImageROI(src, cvRect(x,y,width,height));
		cvAddS(src, cvScalar(add),src);
		cvResetImageROI(src);
		cvShowImage( "大脸猫1",src);
		cvWaitKey();
	}
	cvReleaseImage( &src );
	return 0;
}

显示结果:

利用widthStep方法同样可以把选中区域内所有像素的值加200

#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{

	IplImage* interest_img;
	CvRect interest_rect;
	if( ((interest_img=cvLoadImage("460.jpg")) != 0 ))
	{
		interest_rect.x = atoi("80");
		interest_rect.y = atoi("150");
		interest_rect.width = atoi("270");
		interest_rect.height = atoi("250");
		int add = atoi("1");

		IplImage *sub_img = cvCreateImageHeader(
			cvSize(
			interest_rect.width,
			interest_rect.height
			),
			interest_img->depth,
			interest_img->nChannels
			);

		sub_img->origin = interest_img->origin;

		sub_img->widthStep = interest_img->widthStep;

		sub_img->imageData = interest_img->imageData +
			interest_rect.y * interest_img->widthStep  +
			interest_rect.x * interest_img->nChannels;

		cvAddS( sub_img, cvScalar(add), sub_img );

		cvReleaseImageHeader(&sub_img);

		cvShowImage( "大脸猫22", interest_img );
		cvWaitKey();
	}
	return 0;
}

实验结果:

看起来ROI的方法更方便些,为什么还要使用widthStep呢?原因在于有些时候在处理过程中,想在操作过程中设置和保持一幅图像的多个子区间处于活动状态,但是ROI只能串行处理并且必须不断地设置和重置。所以在实际工作中widthStep更好。

to be continued

《学习opencv》笔记——IplImage数据结构

时间: 2024-10-11 04:12:48

《学习opencv》笔记——IplImage数据结构的相关文章

《学习opencv》笔记——基本数据结构,CvMat,矩阵访问

    老板让让做一个东东,输入端要用到opencv顺便就来学习一下.买了本书<学习opencv>翻来一看,opencv1.0,去官网上一看,opencv2.49,瞬间有种蛋碎的赶脚.看着第二章介绍一个头文件,在opencv2.49下面招了半天都没找到...泪奔~~     不过看到一些论坛上说,这本书里还是讲了一些有用的算法的,所以还是决心仔细读一读,里面的测试程序基本是亲手输入运行成功的,很多例子我自也用不同的方法实现了一下,毕竟入门级新手.望各位老鸟勿喷.还请各位大手多多指点.    

《学习opencv》笔记——基本数据结构,CvMat,矩阵訪问

    老板让让做一个东东.输入端要用到opencv顺便就来学习一下.买了本书<学习opencv>翻来一看,opencv1.0,去官网上一看.opencv2.49,瞬间有种蛋碎的赶脚.看着第二章介绍一个头文件,在opencv2.49以下招了半天都没找到...泪奔~~     只是看到一些论坛上说.这本书里还是讲了一些实用的算法的,所以还是决心细致读一读,里面的測试程序基本是亲手输入执行成功的,非常多样例我自也用不同的方法实现了一下,毕竟入门级新手.望各位老鸟勿喷.还请各位大手多多指点.    

《学习opencv》笔记——矩阵和图像操作——cvDet,cvDit,cvDotProduct,cvEigenVV and cvFlip

矩阵和图像的操作 (1)cvDet函数 其结构 double cvDet(//计算矩阵的行列式 const CvArr* mat ); 实例代码 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <iostream> using namespace std; int main() { double va[] = {1,0,0,0,2,0,0,0,3}; CvMat Va=cvMa

《学习opencv》笔记——矩阵和图像操作——cvAdd、cvAddS and cvAddWeighted

矩阵和图像的操作 (1)cvAdd函数 其结构 void cvAdd(//图像加和 const CvArr* src1,//第一个原矩阵 const CvArr* src2,//第二个原矩阵 CvArr* dst, //存放矩阵 const CvArr* mask = NULL: //控制点 ); 就是单纯的将两个图像加和,mask变量控制加和的元素点,相当于"开关的作用"; 程序实例 #include <cv.h> #include <highgui.h> #

《学习opencv》笔记——矩阵和图像操作——cvCrossProduct and cvCvtColor

矩阵和图像的操作 (1)cvCrossProduct函数 其结构 void cvCrossProdust(//计算两个三维向量的叉积 const CvArr* src1, const CvArr* src2, CvArr* dst ); 实例代码 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <iostream> using namespace std; int main()

《学习opencv》笔记——矩阵和图像操作——cvCalcCovarMatrix,cvCmp and cvCmpS

矩阵和图像的操作 (1)cvCalcCovarMatrix函数 其结构 void cvCalcCovarMatrix(计算给定点的均值和协方差矩阵 const CvArr** vects,//给定向量 int count,//给定向量的组数 CvArr* cov_mat,//结果矩阵 CvArr* avg,//根据flag得到结果 int flags//标记位 ); 标记位参数值极其意义 标志参数的具体标志值 意义 CV_COVAR_NORMAL 计算均值和协方差 CV_COVAR__SCRAM

《学习opencv》笔记——矩阵和图像操作——cvSum,cvSVD,cvSVBkSb,cvTrace,cvTranspose,cvXor,cvXorS and cvZero

矩阵和图像的操作 (1)cvSum函数 其结构 CvScalar cvSum(//计算arr各通道所有像素总和 CvArr* arr//目标矩阵 ); 实例代码 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <iostream> using namespace std; int main() { IplImage *src1,*dst1,*dst2,*dst3,*dst4;

《学习opencv》笔记——矩阵和图像操作——cvOr,cvOrS,cvrReduce,cvRepeat,cvScale,cvSet and cvSetZero

矩阵和图像的操作 (1)cvOr函数 其结构 void cvOr(//两个矩阵对应元素做或运行 const CvArr* src1,//矩阵1 const CvArr* src2,//矩阵2 CvArr* dst,//结果矩阵 const CvArr* mask = NULL//矩阵"开关" ); 实例代码 #include <cv.h> #include <highgui.h> #include <stdio.h> int main(int arg

《学习opencv》笔记——矩阵和图像操作——cvAnd、cvAndS、cvAvg and cvAvgSdv

矩阵和图像的操作 (1)cvAnd函数 其结构 void cvAnd( //将src1和src2按像素点取"位与运算" const CvArr* src1,//第一个矩阵 const CvArr* src2,//第二个矩阵 CvArr* dst,//结果矩阵 const CvArr* mask = NULL;//矩阵经行像素点与的"开关" ); 程序实例 #include <cv.h> #include <highgui.h> #includ