OPENCV中图像数据结构及其转化

OPENCV中图像数据结构及其转化

1. IplImage

openCV库中表示图像的结构体

初始化:

cvLoadImage(),cvCreateImage()

访问元素:【行指针】

b = ((uchar *)(img->imageData + row * img->widthStep))[col * img->nChannels + 0];

 

a. IplImage*转Mat

Mat mtx= cvarrToMat(img);   

b. IplImage*CvMat

CvMat matheader;

CvMat * mat = cvGetMat(img, &matheader);

CvMat * mat = cvCreateMat(img->height, img->width, CV_64FC3);

cvConvert(img, mat)

c. IplImage*BYTE*

IplImage* img0 = cvLoadImage("1.bmp");

BYTE* pDst = (unsigned char*)img0->imageData;

 

2. CvMat

cvCreateMat(),cvInitMatHeader()

 

CvMat -> Mat

Mat::Mat(const CvMat* m, bool copyData=false); /*类似IplImage -> Mat,可选择是否复制数据*/

CvMat-> IplImage

IplImage* img = cvCreateImage(cvGetSize(mat),8,1);

cvGetImage(matI,img);

 

3. Mat

矩阵头+指向像素数据的指针。计算时,可以把CvMat 或 IplImage 浅拷贝为 cv::Mat , 然后计算, 计算完再转回CvMat 或 IplImage,可大大提高运算效率.

Mat mat = imread(const String* filename);            读取图像

imshow(const string frameName, InputArray mat);      显示图像

imwrite (const string& filename, InputArray img);    储存图像

【均是直接转成目标类型】

Mat -> IplImage

Mat M

= M; /*只创建图像头,不复制数据*/

Mat -> CvMat

例子(假设Mat类型的imgMat图像数据存在):

CvMat cvMat = imgMat;/*Mat -> CvMat, 类似转换到IplImage,不复制数据只创建矩阵头

关系

Mat类型侧重于计算,能够更加方便的进行内存管理,不再需要程序员手动管理内存的释放,能处理多维数据。

 CvMat和IplImage类型更侧重于“图像”CvArr -> CvMat -> IplImage. CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat处理。

IplImage内部buffer每行是按4字节对齐的,CvMat没有这个限制

我们看到很多函数的参数是InputArray, 而调用的时候传入的是cv::Mat对象

 

4. BYTE*IplImage*

已知BYTE* pDst;

IplImage* img;

img = cvCreateImageHeader(cvSize(img0->width, img0->height), IPL_DEPTH_8U, img0->nChannels);

cvSetData(img, pDst, img0->widthStep);

 

参考:

https://www.cnblogs.com/summerRQ/articles/2406109.html 

http://blog.sina.com.cn/s/blog_afe2af380101bgyn.html 

http://blog.csdn.net/bagboy_taobao_com/article/details/47048249 

 

加载图像与释放

cvLoadImage

每次都会开辟一块新的内存,如果不释放,就会导致内存泄露

1.释放 cvReleaseImage( &src );     src=NULL;

2. 使用CvvImage类代替 覆盖,只需程序结束时释放】

CvvImage pSrcImg;

IplImag *pSrcImgCopy ; //使用IplImag变量做个拷贝。毕竟IplImag 类处理方便。

pSrcImgCopy = cvCreateImage(cvSize(IMGWIDHT,IMGHEIGHT),IPL_DEPTH_8U, 3);// 要正确释放pSrcImgCopy 时,声明时必须create

//获取图像:

pSrcImg.Load(str); //str为Cstring类型的图像文件名

pSrcImgCopy = pSrcImg.GetImage(); //拷贝出pSrcImg的图像数据。

//释放内存

cvReleaseImage(&pSrcImgCopy );

pSrcImg.Destroy();

 

cvCloneImage

每次拷贝是制作图像的完整拷贝包括头、ROI和数据。不会覆盖以前的内容。每次使用时编译器会分配内存空间。

1.直接使用

IplImag *img = cvCloneImage(frame);

2.先释放再使用

IplImag *img = cvCreateImage( cvSize(frame->width,frame->hight), frame->depth, frame->nChannels );

cvReleaseImage(&img);

img = cvCloneImage(frame);

3. 使用cvCopy函数代替

IplImag *img = cvCreateImage( cvSize(frame->width,frame->hight), frame->depth, frame->nChannels );

cvCopy(frame,img,NULL);

 

cvCloneImage与cvCloneMat: 在赋值的同时会开辟一个新的空间给定义的变量,只适合用于变量开始定义,千万不要用在算法处理中间,否则会产生一个新的地址空间,会将赋值对象的指针地址改变,这样会导致整个程序有不可预测的错误发生

cvCopyImage与cvCopyMat: 只复制值,并不会分配一个空间给赋值对象。建议在程序中间进行复制时使用。

 

cvGetCols()、cvGetRows()同理

1.CvMat *srcMat = cvCreateMat(width, height, CV_8UC3);  // 创建一个三通道无符号整数类型的矩阵

cvReleaseData(srcMat);    // 先释放目标矩阵的数据区

cvGetCols(frame,srcMat,0,width);

2.cvCreateMatHeader(width, height, CV_8UC3);

cvGetCols(frame,srcMat,0,width);

 

IplImag*、CvMat*、CvHistogram* 等结构体指针在使用后要释放

IplImage *frame= cvCreateImage(cvSize(width,height),8,1);

CvMat *srcMat = cvCreateMat(width, height, CV_8U);

CvHistogram *hist = cvCreateHist(1,&histSize,CV_HIST_ARRAY,ranges,1);

......

cvReleaseMat(&srcMat);

cvReleaseImage(&frame);  

cvReleaseHist(&hist);

 

参考:

http://blog.sina.com.cn/s/blog_51c1ed0501011g0c.html 

http://blog.csdn.net/shangyaowei/article/details/17424507

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值