• <noscript id="ecgc0"><kbd id="ecgc0"></kbd></noscript>
    <menu id="ecgc0"></menu>
  • <tt id="ecgc0"></tt>

    OpenCV:widthStep vs step

    緒:

    在OpenCV中,widthStep是相對于IplImage*進行圖像像素拜候操作的;

    而step是相對于Mat進行圖像像素拜候操作的;

    widthStep:存儲一行像素需要的字節數;

    step:每一行中所有元素的字節總量,單元字節;

    本文本家兒要介紹:

    widthStep界說;widthStep在IplImage中的感化;widthStep在圖像像素拜候中的應用;

    widthStep總結;

    step在Mat類中的感化;step在圖像像素拜候中的應用;

    東西/原料

    • OpenCV 2410

    方式/步調

    1. 1

      widthStep界說:

      ①OpenCV中,默認圖像原點為圖像左上角,img->origin=IPL_ORIGIN_TL;若是想更改圖像原點坐標也可以,如img->origin=IPL_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。

    2. 2

      widthStep在IplImage*中的感化:

      如下:

      typedef struct _IplImage{

          int  nSize;             /* sizeof(IplImage) */

          int  ID;                /* version (=0)*/

          int  nChannels;         /* Most of OpenCV functions support 1,2,3 or 4 channels */

          int  alphaChannel;      /* Ignored by OpenCV */

          int  depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported.  */

          char colorModel[4];     /* Ignored by OpenCV */

          char channelSeq[4];     /* ditto */

          int  dataOrder;         /* 0 - interleaved color channels, 1 - separate color channels.

                                     cvCreateImage can only create interleaved images */

          int  origin; /* 0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style).  */

          int  align; /* Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead. */

          int  width;             /* Image width in pixels.                           */

          int  height;            /* Image height in pixels.                          */

          struct _IplROI *roi;    /* Image ROI. If NULL, the whole image is selected. */

          struct _IplImage *maskROI;      /* Must be NULL. */

          void  *imageId;                 /* "           " */

          struct _IplTileInfo *tileInfo;  /* "           " */

          int  imageSize;  /* Image data size in bytes (==image->height*image->widthStep in case of interleaved data)*/

          char *imageData;        /* Pointer to aligned image data.         */

          int  widthStep;         /* Size of aligned image row in bytes.    */

          int  BorderMode[4];     /* Ignored by OpenCV.                     */

          int  BorderConst[4];    /* Ditto.                                 */

          char *imageDataOrigin;  /* Pointer to very origin of image data (not necessarily aligned) -

                                     needed for correct deallocation */

      }IplImage;

    3. 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];

    4. 4

      widthStep常識總結:

      width暗示圖像的每行像素數,

      widthStep暗示存儲一行像素需要的字節數,widthStep必需是4的倍數,從而實現字節對齊,有利于提高運算速度。

      若是8U單通道圖像寬度為3,那么widthStep是4,加一個字節補齊。

      這個圖像的一行需要4個字節,只利用前3個,最后一個空著。

      也就是一個寬3高3的圖像的imageData數據巨細為4*3=12字節。

      【注】:分歧數據類型長度的圖像,widthStep也不不異;

      widthStep的值的計較有兩種環境:

      ①當(width*3)%4=0,這時width*3=widthStep;

      ②當(width*3)%4 !=0,此時widthStep=(width/4+1)*3。

      Mat的數據并不是字節對齊的;

      直接將cv::Mat轉換為IplImage類型,并不會將字節對齊,只是加了個文件頭罷了;

      是以需要如下操作:

    5. 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。

    6. 6

      Mat拜候圖像像素---step:

      data:unsigned char類型的指針,指標的目的Mat數據矩陣的首地址;

      dims:Mat矩陣的維度;

      rows:Mat矩陣的行數;

      cols:Mat矩陣的列數;

      size():是一個布局體,有image.size().width==image.cols; image.size().height==image.rows

      channels():Mat矩陣元素擁有的通道數;

      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}

      elemSize:暗示矩陣中每一個元素的數據巨細,單元字節,若是Mat中的數據類型是CV_8UC1,那么elemSize==1;若是是CV_8UC3或CV_8SC3,那么elemSize==3;若是是CV_16UC3或者CV_16SC3,那么elemSize==6;即elemSize是以8位(一個字節)為一個單元,乘以通道數和8位的整數倍;

      elemSize1:

      暗示Mat矩陣中每一個元素單個通道的數據巨細,單元字節,elemSize1=elemSize/channels;

      step:為Mat矩陣中每一行的“步長”,以字節為根基單元,每一行中所有元素的字節總量;

      step1():以字節為根基單元,Mat矩陣中每一個像素的巨細step1==step/elemSize1;

      type:Mat矩陣的類型,包含有矩陣中元素的類型、通道數信息,type的定名格局為CV_(位數)+(數據類型)+(通道數),如下:

    7. 7

      Mat拜候圖像像素---step

      step:為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];

    注重事項

    • step拜候圖像像素的形式;
    • widthStep拜候圖像像素的形式;
    • 發表于 2018-05-05 00:00
    • 閱讀 ( 1330 )
    • 分類:其他類型

    你可能感興趣的文章

    相關問題

    0 條評論

    請先 登錄 后評論
    admin
    admin

    0 篇文章

    作家榜 ?

    1. xiaonan123 189 文章
    2. 湯依妹兒 97 文章
    3. luogf229 46 文章
    4. jy02406749 45 文章
    5. 小凡 34 文章
    6. Daisy萌 32 文章
    7. 我的QQ3117863681 24 文章
    8. 華志健 23 文章

    聯系我們:uytrv@hotmail.com 問答工具
  • <noscript id="ecgc0"><kbd id="ecgc0"></kbd></noscript>
    <menu id="ecgc0"></menu>
  • <tt id="ecgc0"></tt>
    久久久久精品国产麻豆