IplImage的像素的访问.doc_第1页
IplImage的像素的访问.doc_第2页
IplImage的像素的访问.doc_第3页
IplImage的像素的访问.doc_第4页
IplImage的像素的访问.doc_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

l IplImage的像素的访问当处理图象数据时,通常需要快速高效。使用如cvSet*D或和它等效的函数会造成调用时的开销。我们应该尽可能使用直接存取图象内部数据的方法。有了IplImage内部结构的知识,我们现在可以理解最好的方法。尽管通常OpenCV提供很多对图象的操作优化良好的例程,但是经常会有些任务是库里找不到包装好的例程的。下面我们考虑一个例子,我们想要把三通道HSV图象的饱合度调整为255(8位图象的最大值)而保持色调不变。要完成这个任务最好是我们自己处理图象的每个象素。这和我们前边对矩阵的操作相似,但在IplImage和CvMat之间也有一些主要的不同。例3-11演示了高效的方式。例3-11,把HSV图象的S、V分量最大化:void saturate_sv( IplImage* img ) for( int y=0; yheight; y+ ) uchar* ptr = (uchar*) (img-imageData + y * img-widthStep); for( int x=0; xwidth; x+ ) ptr3*x+1 = 255; ptr3*x+2 = 255; 我们只是简单的直接计算相关行y最左边的象素的指针ptr(We simply compute the pointer ptr directly as the head of the relevant row y)。从那里为参考,我们引用第x列的饱合度数值。因为图象是三通道的,第c通道的地址为3*x+c。在OpenCV中,一副HSV图象和RGB图象,除了对通道的翻译有所不同,其它是没有区别的。因此由一副HSV图象构建一副RGB图象实际所有的操作完全只在“数据”区域。在图象头中,没有任何成员用来表明数据通道的意义。IplImage和CvMat相比一个重要的不同是imageData的行为。CvMat的数据元素是一个联合体,所以必须说明你想要的指针类型;imageData是一个byte型(uchar*)。我们已经知道被指向的数据不一定是uchar类型,这意味着当对指针作算术运算时,你可以简单的加上widthSetp(同样是以字节数为度量的)而不用担心实际的数据类型,直需在做完加法后,把你计算所得的指针转换成你想要的数据类型。总结:当对矩阵操作时,你必须对偏移量进行缩减,因为数据指针可能不是byte型;而当对图象操作时,你可以使用“看上去”那么多的偏移量,因为数据指针永远是byte型,因此在你准备使用它时,只需把整部分做类型转换。访问图象数据的补充资料资料来源:OpenCV中文网站(1) 假设你要访问第k通道、第i行、第j列的像素。(2) 间接访问: (通用,但效率低,可访问任意格式的图像)对于单通道字节型图像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);CvScalar s;s=cvGet2D(img,i,j);/ get the (i,j) pixel valueprintf(intensity=%fn,s.val0);s.val0=111;cvSet2D(img,i,j,s);/ set the (i,j) pixel value 对于多通道字节型/浮点型图像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);CvScalar s;s=cvGet2D(img,i,j);/ get the (i,j) pixel valueprintf(B=%f, G=%f, R=%fn,s.val0,s.val1,s.val2);s.val0=111;s.val1=111;s.val2=111;cvSet2D(img,i,j,s);/ set the (i,j) pixel value (3) 直接访问: (效率高,但容易出错)对于单通道字节型图像: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 (4) 基于指针的直接访问: (简单高效)对于单通道字节型图像: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;datai*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;datai*step+j*channels+k = 111; 对于多通道浮点型图像(假设图像数据采用4字节(32位)行对齐方式):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;datai*step+j*channels+k = 111; ROI和widthStep更多的信息ROI和widthStep有非常重要的实用价值,因为它允许代码只处理图象的一部分子区域,从而在很多场和加速计算机视觉的处理。OpenCV对ROI和widthSetp的支持是普遍的:每一个函数都充许把操作只限定在一个子区域。使用cvSetImageROI( )和cvResetImageROI( )可以开启或关闭ROI。void cvSetImageROI( IplImage* image, CvRect rect );void cvResetImageROI( IplImage* image );为了看ROI是怎么使用的,我们载入一张图片,然后变更图象的一部分。在显示之前用cvResetImageROI( )释放ROI是很重要的,否则只会忠实的显示ROI区域。#include#includeintmain() IplImage *src = cvLoadImage(poppy.jpg, 1);/载入图象 cvSetImageROI(src, cvRect(200, 100, 100, 100);/为图象设置ROI区域 cvAddS(src, cvScalar(100, 100, 100), src);/对图象做与运算 cvResetImageROI(src);/释放ROI区域 cvSaveImage(poppy1.jpg, src);/保存处理后的图象 cvNamedWindow(Roi_add);/创建一个窗口 cvShowImage(Roi_add, src);/在窗口上显示图象 cvWaitKey();/延时 return0;如果我们灵活的使用widthStep,也可以达到相同的效果。#include#includeintmain() IplImage *src = cvLoadImage(poppy.jpg, 1); /载入图象 CvRect interest_rect = cvRect(200, 100, 100, 100);/用CvRect结构设定一个感兴趣的区域 IplImage *sub_img = cvCreateImageHeader( cvSize(interest_rect.width, interest_rect.height), src-depth, src-nChannels );/创建一个和源图象属性相同的子图象 sub_img-origin = src-origin; /设定相同P的原点标准 sub_img-widthStep = src-widthStep;/设定子图象的widthStep,这是此技术中最精妙的一笔 sub_img-imageData = src-imageData + interest_rect.y * src-widthStep + interest_rect.x * src-nChannels;/设定子图象的数据区域 cvAddS(sub_img, cvScalar(100, 100, 100), sub_img);/对图象做与运算 cvReleaseImageHeader(&sub_img); /释放子图象头 cvSaveImage(poppy1.jpg, src);/保存处理后的图象 cvNamedWindow(Roi_add); /创建一个窗口 cvShowImage(Roi_add, src); /显示图象 cvWaitKey();/延时 return0;设定和重置ROI区域好像更方便,那么为什么还想要用widthStep耍花招呢。这样做的原因是有时候在图像处理过程中需要保持多

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论