OpenCV基础知识——多维矩阵

来源:互联网 发布:mac中英文怎么切换 编辑:程序博客网 时间:2024/05/14 14:56

       多维矩阵的结构分析:

例子:

  1. #include "cv.h"
  2. #include "highgui.h"
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <string>
  6. void main()
  7.     int size[]={2,3,4};
  8.     CvMatND *myND=cvCreateMatND(3,size,CV_8SC1);
  9.     printf("1 size=%d    step=%d/n",myND->dim[0]);
  10.    printf("2 size=%d    step=%d/n",myND->dim[1]);
  11.    printf("3 size=%d    step=%d/n",myND->dim[2]);
  12. }

结果:

  1. 1      size=2    step=12
  2. 2      size=3    step=4
  3. 3      size=4    step=1

经过OpenCV源代码分析:

       (1)在cvCreateMatND函数中先后又调用了cvCreateMatNDHeader和cvCreateData函数。

          源码:

  1. CV_IMPL CvMatND*
  2. cvCreateMatND( int dims, const int* sizes, int type )
  3. {
  4.     CvMatND* arr = 0;
  5.     CV_FUNCNAME( "cvCreateMatND" );
  6.     
  7.     __BEGIN__;
  8.     CV_CALL( arr = cvCreateMatNDHeader( dims, sizes, type ));
  9.     CV_CALL( cvCreateData( arr ));
  10.     __END__;
  11.     if( cvGetErrStatus() < 0 )
  12.         cvReleaseMatND( &arr );
  13.     return arr;
  14. }

      (2)在cvCreateMatNDHeader中,首先为CvMatND结构体分配了内存,然后接着调用了cvInitMatNDHeader函数。

         源码:

  1. CV_IMPL CvMatND*
  2. cvCreateMatNDHeader( int dims, const int* sizes, int type )
  3. {
  4.     CvMatND* arr = 0;
  5.     
  6.     CV_FUNCNAME( "cvCreateMatNDHeader" );
  7.     __BEGIN__;
  8.     if( dims <= 0 || dims > CV_MAX_DIM )
  9.         CV_ERROR( CV_StsOutOfRange,
  10.         "non-positive or too large number of dimensions" );
  11.     CV_CALL( arr = (CvMatND*)cvAlloc( sizeof(*arr) ));
  12.     
  13.     CV_CALL( cvInitMatNDHeader( arr, dims, sizes, type, 0 ));
  14.     arr->hdr_refcount = 1;
  15.     __END__;
  16.     if( cvGetErrStatus() < 0 )
  17.         cvReleaseMatND( &arr );
  18.     return arr;
  19. }

  (3)在cvInitMatNDHeader中,其初始化了结构体CvMatND的各个成员变量。

源码:

  1. CV_IMPL CvMatND*
  2. cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
  3.                     int type, void* data )
  4. {
  5.     CvMatND* result = 0;
  6.     CV_FUNCNAME( "cvInitMatNDHeader" );
  7.     __BEGIN__;
  8.     type = CV_MAT_TYPE(type);
  9.     int i;
  10.     int64 step = CV_ELEM_SIZE(type);
  11.     if( !mat )
  12.         CV_ERROR( CV_StsNullPtr, "NULL matrix header pointer" );
  13.     if( step == 0 )
  14.         CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );
  15.     if( !sizes )
  16.         CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );
  17.     if( dims <= 0 || dims > CV_MAX_DIM )
  18.         CV_ERROR( CV_StsOutOfRange,
  19.         "non-positive or too large number of dimensions" );
  20.     for( i = dims - 1; i >= 0; i-- )
  21.     {
  22.         if( sizes[i] <= 0 )
  23.             CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );
  24.         mat->dim[i].size = sizes[i];
  25.         if( step > INT_MAX )
  26.             CV_ERROR( CV_StsOutOfRange, "The array is too big" );
  27.         mat->dim[i].step = (int)step;
  28.         step *= sizes[i];
  29.     }
  30.     mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type;
  31.     mat->dims = dims;
  32.     mat->data.ptr = (uchar*)data;
  33.     mat->refcount = 0;
  34.     mat->hdr_refcount = 0;
  35.     result = mat;
  36.     __END__;
  37.     if( cvGetErrStatus() < 0 && mat )
  38.     {
  39.         mat->type = 0;
  40.         mat->data.ptr = 0;
  41.     }
  42.     return result;
  43. }
  44. (4)cvCrateData源码如下所示

 

  1. 源码:
    1. CV_IMPL void
    2. cvCreateData( CvArr* arr )
    3. {
    4.     CV_FUNCNAME( "cvCreateData" );
    5.     
    6.     __BEGIN__;
    7.     if( CV_IS_MAT_HDR( arr ))
    8.     {
    9.         size_t step, total_size;
    10.         CvMat* mat = (CvMat*)arr;
    11.         step = mat->step;
    12.         if( mat->data.ptr != 0 )
    13.             CV_ERROR( CV_StsError, "Data is already allocated" );
    14.         if( step == 0 )
    15.             step = CV_ELEM_SIZE(mat->type)*mat->cols;
    16.         total_size = step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
    17.         CV_CALL( mat->refcount = (int*)cvAlloc( (size_t)total_size ));
    18.         mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
    19.         *mat->refcount = 1;
    20.     }
    21.     else if( CV_IS_IMAGE_HDR(arr))
    22.     {
    23.         IplImage* img = (IplImage*)arr;
    24.         if( img->imageData != 0 )
    25.             CV_ERROR( CV_StsError, "Data is already allocated" );
    26.         if( !CvIPL.allocateData )
    27.         {
    28.             CV_CALL( img->imageData = img->imageDataOrigin = 
    29.                         (char*)cvAlloc( (size_t)img->imageSize ));
    30.         }
    31.         else
    32.         {
    33.             int depth = img->depth;
    34.             int width = img->width;
    35.             if( img->depth == IPL_DEPTH_32F || img->nChannels == 64 )
    36.             {
    37.                 img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
    38.                 img->depth = IPL_DEPTH_8U;
    39.             }
    40.             CvIPL.allocateData( img, 0, 0 );
    41.             img->width = width;
    42.             img->depth = depth;
    43.         }
    44.     }
    45.     else if( CV_IS_MATND_HDR( arr ))
    46.     {
    47.         CvMatND* mat = (CvMatND*)arr;
    48.         int i;
    49.         size_t total_size = CV_ELEM_SIZE(mat->type);
    50.         if( mat->data.ptr != 0 )
    51.             CV_ERROR( CV_StsError, "Data is already allocated" );
    52.         if( CV_IS_MAT_CONT( mat->type ))
    53.         {
    54.             total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?
    55.                          mat->dim[0].step : total_size);
    56.         }
    57.         else
    58.         {
    59.             for( i = mat->dims - 1; i >= 0; i-- )
    60.             {
    61.                 size_t size = (size_t)mat->dim[i].step*mat->dim[i].size;
    62.                 if( total_size < size )
    63.                     total_size = size;
    64.             }
    65.         }
    66.         
    67.         CV_CALL( mat->refcount = (int*)cvAlloc( total_size +
    68.                                         sizeof(int) + CV_MALLOC_ALIGN ));
    69.         mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
    70.         *mat->refcount = 1;
    71.     }
    72.     else
    73.     {
    74.         CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
    75.     }
    76.     __END__;
    77. }
原创粉丝点击