大家好,小经来为大家解答以上问题。width是什么指标,widthstep很多人还不知道,现在让我们一起来看看吧!
1、 宽度步长定义:
2、 OpenCV中,默认图像原点为图像左上角,img-ORIGIN=IPL_ORIGIN_TL;如果想更改图像原点坐标也可以,如img-origin=IPL_ORIGIN_BL,将图像原点更改为左下角;
3、 一般采用默认的图像原点;
4、 OpenCV用从文件读取图象或者cvLoadImage得到的图像数据都是无符号字符类型的;
5、 IplImage结构体中的宽度步长元素大小不一定等于宽度*n通道,
6、 在cxcore/cxarray.cpp文件中,cvInitImageHeader对宽度步长大小赋值:
7、 图像宽度步长=
8、 (((image-width*image-nChannels*(image-DEPTH~IPL_DEPTH_SIGN)7)/8)align-1)(~(align-1));
9、 其中,
10、 cxtypes.h定义IPL_深度_符号为:#defineIPL_DEPTH_SIGN0x80000000;
11、 cxmisc.h中定义排列为:#defineCV_DEFAULT_IMAGE_ROW_ALIGN4;
12、 深度取8位深度;
13、 则可计算图像的宽度步长;
14、 一些图像的宽度步长如下:
15、 IPLimage*image_33=cvCreateImage(cvSize(3,3),8,3);
16、 IPLimage*image_31=cvCreateImage(cvSize(3,3),8,1);
17、 IPLimage*image_53=cvCreateImage(cvSize(5,3),8,3);
18、 IPLimage*image_51=cvCreateImage(cvSize(5,3),8,1);
19、 IPLimage*image_73=cvCreateImage(cvSize(7,3),8,3);
20、 IPLimage*image_71=cvCreateImage(cvSize(7,3),8,1);
21、 printf('%d,%d,%d,%d,%d,%d',
22、 图片_33-宽度步长,
23、 图片_31-宽度步长,
24、 图片_53-宽度步长,
25、 图片_51-宽度步长,
26、 图片_73-宽度步长,
27、 image_71-宽度步长);
28、 运行结果为:12,4,16,8,24,8。
29、 因此,OpenCV分配的内存按四字节对齐,与上述计算结果相符,如宽度为3、通道数为3的图像,每一行需要的实际内存长度为3*3,为了内存对齐,OpenCV会在每行末尾自动补上3个字节的内存,内存初始化都为0,所以宽度步长变为了12。
30、 宽度步长在IplImage*中的作用:
31、 如下:
32、 typedefstruct_IplImage{
33、 intnSize/*sizeof(IplImage)*/
34、 intID/*版本(=0)*/
35、 intnChannels/*大多数开放计算机视觉函数支持1、2、3或四通道*/
36、 频道间;/*被开放计算机视觉忽略*/
37、 (同Internationalorganizations)国际组织深度;/*像素深度位:支持IPL_DEPTH_8U、IPL_DEPTH_8S、IPL_DEPTH_16S、IPL_DEPTH_32S、IPL_DEPTH_32F和IPL_DEPTH_64F.*/
38、 char颜色模型[4];/*被开放计算机视觉忽略*/
39、 充电通道序列[4];/*同上*/
40、 intdataOrder/*0-交错颜色通道,1-独立颜色通道。
41、 cvCreateImage只能创建交错图像*/
42、 (同Internationalorganizations)国际组织原点;/*0-左上角原点,1-左下角原点(Windows位图样式)。*/
43、 intalign/*图像行对齐(4或8)。OpenCVigno
44、intwidth;/*Imagewidthinpixels.*/
45、intheight;/*Imageheightinpixels.*/
46、struct_IplROI*roi;/*ImageROI.IfNULL,thewholeimageisselected.*/
47、struct_IplImage*maskROI;/*MustbeNULL.*/
48、void*imageId;/*""*/
49、struct_IplTileInfo*tileInfo;/*""*/
50、intimageSize;/*Imagedatasizeinbytes(==image->height*image->widthStepincaseofinterleaveddata)*/
51、char*imageData;/*Pointertoalignedimagedata.*/
52、intwidthStep;/*Sizeofalignedimagerowinbytes.*/
53、intBorderMode[4];/*IgnoredbyOpenCV.*/
54、intBorderConst[4];/*Ditto.*/
55、char*imageDataOrigin;/*Pointertoveryoriginofimagedata(notnecessarilyaligned)-
56、neededforcorrectdeallocation*/
57、}IplImage;
58、IplImage*访问图像像素:widthStep
59、对8bit,单通道,unsignedchar类型的图像I---IplImage*img:
60、I(x,y)~((unsignedchar*)(img->imageData+img->widthStep*y))[x];
61、对8bit,3通道,unsignedchar类型的图像I---IplImage*img:
62、I(x,y)blue~((unsignedchar*)(img->imageData+img->widthStep*y))[x*3];
63、I(x,y)green~((unsignedchar*)(img->imageData+img->widthStep*y))[x*3+1];
64、I(x,y)red~((unsignedchar*)(img->imageData+img->widthStep*y))[x*3+2];
65、或者
66、unsignedchar*ptr=&((unsignedchar*)(img->imageData+img->widthStep*y))[x*3];
67、I(x,y)blue~ptr[0];
68、I(x,y)green~ptr[1];
69、I(x,y)red~ptr[2];
70、对32bit,1通道,float*类型的图像I---IplImage*img:
71、I(x,y)~((float*)(img->imageData+img->widthStep*y))[x];
72、对32bit,3通道,float*类型的图像I---IplImage*img;
73、I(x,y)blue~((float*)(img->imageData+img->widthStep*y))[3*x];
74、I(x,y)green~((float*)(img->imageData+img->widthStep*y))[x*3+1];
75、I(x,y)red~((float*)(img->imageData+img->widthStep*y))[x*3+2];
76、对64bit,3通道,double*类型的图像数据I---IplImage*img;
77、image=cvCreateImage(cvSize(111,113),IPL_DEPTH_64F,3);
78、这里widthstep=(111*3*sizeof(double)+3)/4*4=2664;因为111*3*sizeof(double)=2664已经正好是4的倍数了,因此无需补充字节。
79、如果用指针访问第31行、51列的图像数据,
80、则这个数据为double类型的,image->imageData为unsignedchar类型,
81、因此可以转换成double,通过double指针来访问:
82、①
83、double*data=(double*)image->imageData;
84、doubleval=*(data+31*width+51);
85、②或者通过unsignedchar指针找到(31,51)处的地址,
86、然后转换成double指针进行访问:
87、unsignedchar*data=image->imageData;
88、doubleval=*(double*)(data+31*image->widthStep+51*sizeof(double));
89、对于IplImage,指针访问可以参考以上两种方式,其实这本质就是数据类型的转换而已。
90、一般,访问图像像素方法,格式:
91、对于N通道,T类型的图像,
92、I(x,y)c~((T*)(img->imageData+img->widthStep*y))[x*N+c];
93、widthStep知识总结:
94、width表示图像的每行像素数,
95、widthStep表示存储一行像素需要的字节数,widthStep必须是4的倍数,从而实现字节对齐,有利于提高运算速度。
96、如果8U单通道图像宽度为3,那么widthStep是4,加一个字节补齐。
97、这个图像的一行需要4个字节,只使用前3个,最后一个空着。
98、也就是一个宽3高3的图像的imageData数据大小为4*3=12字节。
99、【注】:不同数据类型长度的图像,widthStep也不相同;
100、widthStep的值的计算有两种情况:
101、①当(width*3)%4=0,这时width*3=widthStep;
102、②当(width*3)%4!=0,此时widthStep=(width/4+1)*3。
103、Mat的数据并不是字节对齐的;
104、直接将cv::Mat转换为IplImage类型,并不会将字节对齐,只是加了个文件头而已;
105、因此需要如下操作:
106、BYTE*与IplImage*之间的转换:
107、IplImage*iplImage:opencv中图像数据头;
108、BYTE*data:内存中的图像数据,一般为工业相机采集的图像数据;
109、①由IplImage*转BYTE*图像数据:
110、data=iplImage->imageDataOrigin;//未对齐的原始图像数据
111、或者
112、data=iplImage->imageData;//已对齐的图像数据
113、②BYTE*转IplImage*图像数据
114、iplImage=cvCreateImageHeader(cvSize(width,height),depth,channels);
115、cvSetData(iplImage,data,step);
116、首先,由cvCreateImageHeader()创建IplImage图像头,设置图像尺寸、深度和通道数;
117、然后,由cvSetData()根据BYTE*图像数据指针设置IplImage图像头的数据,
118、其中,step指定该IplImage图像,每行占的字节数,对于1通道的IPL_DEPTH_8U图像,step可以等于width。
119、Mat访问图像像素---step:
120、data:unsignedchar类型的指针,指向Mat数据矩阵的首地址;
121、dims:Mat矩阵的维度;
122、rows:Mat矩阵的行数;
123、cols:Mat矩阵的列数;
124、size():是一个结构体,有image.size().width==image.cols;image.size().height==image.rows
125、channels():Mat矩阵元素拥有的通道数;
126、depth:度量每一个像素中每一个通道的精度,但它本身与图像的通道数无关!depth数值越大,精度越高。在Opencv中,Mat.depth()得到的是一个0~6的数字,分别代表不同的位数,如下:{CV_8U=0,CV_8S=1,CV_16U=2,CV_16S=3,CV_32S=4,CV_32F=5,CV_64F=6}
127、elemSize:表示矩阵中每一个元素的数据大小,单位字节,如果Mat中的数据类型是CV_8UC1,那么elemSize==1;如果是CV_8UC3或CV_8SC3,那么elemSize==3;如果是CV_16UC3或者CV_16SC3,那么elemSize==6;即elemSize是以8位(一个字节)为一个单位,乘以通道数和8位的整数倍;
128、elemSize1:
129、表示Mat矩阵中每一个元素单个通道的数据大小,单位字节,elemSize1=elemSize/channels;
130、step:为Mat矩阵中每一行的“步长”,以字节为基本单位,每一行中所有元素的字节总量;
131、step1():以字节为基本单位,Mat矩阵中每一个像素的大小step1==step/elemSize1;
132、type:Mat矩阵的类型,包含有矩阵中元素的类型、通道数信息,type的命名格式为CV_(位数)+(数据类型)+(通道数),如下:
133、Mat访问图像像素---step
134、step:为Mat矩阵中每一行的“步长”,以字节为基本单位,每一行中所有元素的字节总量;
135、经常应用在访问图像像素操作中;如下:
136、对8bit,单通道,unsignedchar类型的图像I---Matimg:
137、unsignedchar*pData=(unsignedchar*)img.data;
138、I(x,y)~pData[img.step*y+x];//
139、对8bit,3通道,unsignedchar类型的图像I---IplImage*img:
140、I(x,y)blue~((unsignedchar*)(img.data+img.step*y))[x*3];
141、I(x,y)green~((unsignedchar*)(img.data+img.step*y))[x*3+1];
142、I(x,y)red~((unsignedchar*)(img.data+img.step*y))[x*3+2];
143、对32bit,1通道,float*类型的图像I---Matimg:
144、I(x,y)~((float*)(img.data+img.step*y)[x];
145、对32bit,3通道,float*类型的图像I---Matimg;
146、I(x,y)blue~((float*)(img.data+img.step*y))[3*x];
147、I(x,y)green~((float*)(img.data+img.step*y))[x*3+1];
148、I(x,y)red~((float*)(img.data+img.step*y))[x*3+2];
149、对64bit,1通道,double*类型的图像I---Matimg:
150、I(x,y)~((double*)(img.data+img.step*y)[x];
151、对64bit,3通道,double*类型的图像数据I---Matimg;
152、I(x,y)blue~((double*)(img.data+img.step*y))[3*x];
153、I(x,y)green~((double*)(img.data+img.step*y))[x*3+1];
154、I(x,y)red~((double*)(img.data+img.step*y))[x*3+2];
155、一般,访问图像像素方法,格式:
156、对于N通道,T类型的图像,
157、I(x,y)c~((T*)(img.Data+img.step*y))[x*N+c];
本文到此结束,希望对大家有所帮助。