新经网logo.png新经网

新经网
新经网是百姓城市生活中不可缺少的信息港。
新经网

width是什么指标(widthstep)

导读 大家好,小经来为大家解答以上问题。width是什么指标,widthstep很多人还不知道,现在让我们一起来看看吧!1、宽度步长定义:2、OpenCV中,

大家好,小经来为大家解答以上问题。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];

本文到此结束,希望对大家有所帮助。

相关推荐



最新文章