OpenCV:widthStep vs step

 时间:2024-10-15 22:46:36

1、widthStep定义:①OpenCV中,默认图闻赙酵枭像原点为图像左上角,img->origin=IPL_ORIGIN_TL;如果想更改图像原点坐标也可以,如img->origin=IP讣嘬铮篌L_ORIGIN_BL,将图像原点更改为左下角;一般采用默认的图像原点;②OpenCV用imread或者cvLoadImage得到的图像数据都是unsigned char类型的;③IplImage结构体中的widthStep元素大小不一定等于width*nChannels,④在cxcore/cxarray.cpp文件中,cvInitImageHeader对widthStep大小赋值:image->widthStep =(((image->width * image->nChannels *(image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1)); 其中,cxtypes.h定义IPL_DEPTH_SIGN为:#define IPL_DEPTH_SIGN 0x80000000;cxmisc.h中定义align为:#define CV_DEFAULT_IMAGE_ROW_ALIGN 4;depth取8位深度;则可计算图像的widthStep;一些图像的widthStep如下:IplImage *image_33 = cvCreateImage(cvSize(3, 3), 8, 3);IplImage *image_31 = cvCreateImage(cvSize(3, 3), 8, 1);IplImage *image_53 = cvCreateImage(cvSize(5, 3), 8, 3);IplImage *image_51= cvCreateImage(cvSize(5, 3), 8, 1);IplImage *image_73 = cvCreateImage(cvSize(7, 3), 8, 3);IplImage *image_71 = cvCreateImage(cvSize(7, 3), 8, 1);printf("%d, %d, %d, %d, %d, %d",image_33->widthStep,image_31->widthStep,image_53->widthStep,image_51->widthStep,image_73->widthStep,image_71->widthStep);运行结果为:12, 4, 16, 8, 24, 8。因此,OpenCV分配的内存按4字节对齐,与上述计算结果相符,如宽度为3、通道数为3的图像,每一行需要的实际内存长度为3*3,为了内存对齐,OpenCV会在每行末尾自动补上3个字节的内存,内存初始化都为0,所以widthStep变为了12。

OpenCV:widthStep vs step

3、IplImage*访问图像像素:widthStep对呖分甾胗8bit,单通道,unsigned char类型的图像I---朐袁噙岿IplImage* img:I(x, y)~((unsigned char*)(img->imageData+img->widthStep*y))[x];对8bit,3通道,unsigned char类型的图像I---IplImage* img:I(x, y)blue~((unsigned char*)(img->imageData+img->widthStep*y))[x*3];I(x, y)green~((unsigned char*)(img->imageData+img->widthStep*y))[x*3+1];I(x, y)red~((unsigned char*)(img->imageData+img->widthStep*y))[x*3+2];或者unsigned char* ptr=&((unsigned char*)(img->imageData+img->widthStep*y))[x*3];I(x, y)blue ~ ptr[0];I(x, y)green~ ptr[1];I(x, y)red ~ ptr[2];对32bit,1通道,float*类型的图像I---IplImage* img:I(x, y)~((float*)(img->imageData+img->widthStep*y))[x];对32bit,3通道,float*类型的图像I---IplImage*img;I(x, y) blue ~((float*)(img->imageData+img->widthStep*y))[3*x];I(x, y) green ~(( float *)(img->imageData+img->widthStep*y))[x*3+1];I(x, y) red ~(( float *)(img->imageData+img->widthStep*y))[x*3+2];对64bit,3通道,double*类型的图像数据I--- IplImage*img;image=cvCreateImage(cvSize(111,113),IPL_DEPTH_64F,3);这里widthstep=(111*3*sizeof(double)+3)/4*4=2664;因为111*3*sizeof(double)=2664已经正好是4的倍数了,因此无需补充字节。如果用指针访问第31行、51列的图像数据,则这个数据为double类型的,image->imageData为unsigned char类型,因此可以转换成double,通过double指针来访问:①double *data=(double*)image->imageData;double val=*(data+31*width+51);②或者通过unsigned char指针找到(31,51)处的地址,然后转换成double指针进行访问:unsigned char* data=image->imageData;double val=*(double*)(data+31*image->widthStep+51*sizeof(double)); 对于IplImage,指针访问可以参考以上两种方式,其实这本质就是数据类型的转换而已。一般,访问图像像素方法,格式:对于N通道,T类型的图像,I(x,y)c~((T*)(img->imageData+img->widthStep*y))[x*N+c];

OpenCV:widthStep vs step

5、BYTE*与IplImage*之间的转换:IplImage* iplImage:opencv中图像数据头;BYTE* data:内存中的图像数据,一般为工业相机采集的图像数据;①由IplImage*转BYTE*图像数据:data = iplImage->imageDataOrigin; //未对齐的原始图像数据或者data = iplImage->imageData; //已对齐的图像数据②BYTE*转IplImage*图像数据iplImage = cvCreateImageHeader(cvSize(width,height),depth,channels);cvSetData(iplImage,data,step);首先,由cvCreateImageHeader()创建IplImage图像头,设置图像尺寸、深度和通道数;然后,由cvSetData()根据BYTE*图像数据指针设置IplImage图像头的数据,其中,step指定该IplImage图像,每行占的字节数,对于1通道的 IPL_DEPTH_8U图像,step可以等于width。

OpenCV:widthStep vs step

7、Mat访问图像像素---stepstep:为Mat矩阵中每一行的“步长”,以字节为基本单位,每一行中所有元素的字节总量;经常应用在访问图像像素操作中;如下:对8bit,单通道,unsigned char类型的图像I---Mat img:unsigned char* pData=(unsigned char*)img.data;I(x, y)~pData[img.step*y+x];//对8bit,3通道,unsigned char类型的图像I---IplImage* img:I(x, y)blue~((unsigned char*)(img.data+img.step*y))[x*3];I(x, y)green~((unsigned char*)(img.data+img.step*y))[x*3+1];I(x, y)red~((unsigned char*)(img.data+img.step*y))[x*3+2];对32bit,1通道,float*类型的图像I---Mat img:I(x, y)~((float*)(img.data+img.step*y)[x];对32bit,3通道,float*类型的图像I--- Mat img;I(x, y) blue ~((float*)(img.data+img.step*y))[3*x];I(x, y) green ~((float*)(img.data+img.step*y))[x*3+1];I(x, y) red ~((float*)(img.data+img.step*y) )[x*3+2];对64bit,1通道,double*类型的图像I---Mat img:I(x, y)~((double*)(img.data+img.step*y)[x];对64bit,3通道,double*类型的图像数据I--- Mat img;I(x, y) blue ~(( double *)(img.data+img.step*y))[3*x];I(x, y) green ~(( double *)(img.data+img.step*y))[x*3+1];I(x, y) red ~(( double *)(img.data+img.step*y))[x*3+2];一般,访问图像像素方法,格式:对于N通道,T类型的图像,I(x,y)c~((T*)(img.Data+img.step *y))[x*N+c];

OpenCV:widthStep vs stepOpenCV:widthStep vs step
  • 关于木炭进口报关流程及手续全面解析
  • 为什么PCM中不用NRZ码呢?
  • 逻辑与(&&)
  • word 2013:如何在word中插入网络上的图片
  • 京东长辈版怎么切换
  • 热门搜索
    皮囊炎是怎么引起的 减肥普拉提 铁骆驼电瓶修复怎么样 婴儿奶粉怎么冲 怎么样去痘痘 眼跳是怎么回事 肖邦简介 超级攻略之神 问道手游怎么交易 什么食物可以减肥