[OpenCV] Basic data types - Matrix

Ref: http://docs.opencv.org/2.4.13/

 

基础数据结构


一、基本几何

 

  • 矩形

"modules/core/src/drawing.cpp

CV_IMPL void
cvRectangle( CvArr* _img, CvPoint pt1, CvPoint pt2,
             CvScalar color, int thickness,
             int line_type, int shift )
{
    cv::Mat img = cv::cvarrToMat(_img);
    cv::rectangle( img, pt1, pt2, color, thickness, line_type, shift );    
}

 

  • 点 

"modules/core/include/opencv2/core/types_c.h

typedef struct CvPoint
{
    int x;   
    int y;   
}
CvPoint;
typedef struct CvPoint3D64f
{
    double x;
    double y;
    double z;
}
CvPoint3D64f;

 

  • 面积

typedef struct CvSize
{
    int width;
    int height;
}
CvSize;

 

  • 大数表示 (例如:表示颜色)

typedef struct CvScalar
{
    double val[4];
}
CvScalar;

 

 

二、矩阵描述

  • Mat

Ref: opencv基础知识------IplImage, CvMat, Mat 的关系和相互转换

在openCV中,Mat类型与CvMat和IplImage类型都可以代表和显示图像,

但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。

而CvMat和IplImage类型更侧重于“图像”,openCV对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。

 

补充:

IplImage由CvMat派生,而CvMat由CvArr派生即CvArr -> CvMat -> IplImage

CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat处理。

 

 

三、图片描述

  • IplImage 

"modules/core/include/opencv2/core/types_c.h"

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  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;

 

  • CvMat

"modules/core/include/opencv2/core/types_c.h" 708L, 58287C

typedef struct CvMat
{
    int type;
    int step;

    /* for internal use only */
    int* refcount;
    int hdr_refcount;

    union
    {
        uchar*;
        short* s;
        int* i;
        float* fl;
        double* db;
    } data;

#ifdef __cplusplus
    union
    {
        int rows;
        int height;
    };

    union
    {
        int cols;
        int width;
    };
#else
    int rows;
    int cols;
#endif

}
CvMat;

 

[1] 初始化一个矩阵

#include "cv.h"
#include <stdio.h>

int main()
{
  // Create an OpenCV Matrix containing some fixed data.
  //
  float vals[] = { 0.866025, -0.500000, 0.500000, 0.866025};
   
  CvMat rotmat;
   
  cvInitMatHeader(&rotmat, 2, 2, CV_32FC1, vals);
printf(
"Ex 3_3 matrix initialized\n"); }

 

[2] 相关源代码:"modules/core/src/array.cpp"

 

[3] 初始化细节:Init Matrax ( ):

CV_IMPL CvMat*
cvInitMatHeader( CvMat* arr, int rows, int cols,
                 int type, void* data, int step )
{
    if( !arr )
        CV_Error( CV_StsNullPtr, "" );

    if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
        CV_Error( CV_BadNumChannels, "" );

    if( rows < 0 || cols <= 0 )
        CV_Error( CV_StsBadSize, "Non-positive cols or rows" );

    type = CV_MAT_TYPE( type );
    arr->type = type | CV_MAT_MAGIC_VAL;
    arr->rows = rows;
    arr->cols = cols;
    arr->data.ptr = (uchar*)data;
    arr->refcount = 0;
    arr->hdr_refcount = 0;

    int pix_size = CV_ELEM_SIZE(type);
    int min_step = arr->cols*pix_size;

    if( step != CV_AUTOSTEP && step != 0 )
    {
        if( step < min_step )
            CV_Error( CV_BadStep, "" );
        arr->step = step;
    }
    else
    {
        arr->step = min_step;
    }

    arr->type = CV_MAT_MAGIC_VAL | type |
        (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);

    icvCheckHuge( arr );
    return arr;
}

 

[4] 其他相关API:Relevant Functions

// Create a new rows by cols matrix of type ‘type’.
//
CvMat* cvCreateMat( int rows, int cols, int type );
// Create only matrix header without allocating data // CvMat* cvCreateMatHeader( int rows, int cols, int type );
// Initialize header on existing CvMat structure // CvMat*cvInitMatHeader( CvMat* mat, int rows, int cols, int type, void* data = NULL, int step = CV_AUTOSTEP );
// Like cvInitMatHeader() but allocates CvMat as well. // CvMat cvMat( int rows, int cols, int type, void* data = NULL );
// Allocate a new matrix just like the matrix ‘mat’. // CvMat* cvCloneMat( const cvMat* mat );
// Free the matrix ‘mat’, both header and data. // void cvReleaseMat( CvMat** mat );

 

 

四、存取像素点

  • 宏方法

"modules/core/include/opencv2/core/types_c.h"

#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size )  \
    (assert( (unsigned)(row) < (unsigned)(mat).rows &&   \
             (unsigned)(col) < (unsigned)(mat).cols ),   \
     (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))

#define CV_MAT_ELEM_PTR( mat, row, col )                 \
    CV_MAT_ELEM_PTR_FAST( mat, row, col, CV_ELEM_SIZE((mat).type) )

#define CV_MAT_ELEM( mat, elemtype, row, col )           \
    (*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype)))

 宏取值,简单但通用性不强:

#include "cv.h"
#include <stdio.h>

int main()
{
  CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
// 1. 指针法
float element_3_2 = 7.7; *( (float*)CV_MAT_ELEM_PTR( *mat, 3, 2 ) ) = element_3_2;

// 2. 处理“浮点型,单通道矩阵” cvmSet( mat, 2, 2, 0.5000 );

// 3. 较常用 cvSetReal2D( mat,
3, 3, 0.3300 ); printf("Exercise 3_5, matrix created and accessed [3,2]=%f, [2,2]=%f, [3,3]=%f\n",
    CV_MAT_ELEM( *mat, float, 3, 2 ),
    CV_MAT_ELEM( *mat, float, 2, 2 ),
    CV_MAT_ELEM( *mat, float, 3, 3 ) ); }

 

  • Get pixel

"modules/core/src/array.cpp"

// CvMat and IplImage element functions
double cvGetReal1D( const  CvArr* arr, int idx0 );
double cvGetReal2D( const  CvArr* arr, int idx0, int idx1 );
double cvGetReal3D( const  CvArr* arr, int idx0, int idx1, int idx2 );
double cvGetRealND( const  CvArr* arr, int* idx );
CvScalar cvGet1D(
const CvArr* arr, int idx0 ); CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 ); CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 ); CvScalar cvGetND( const CvArr* arr, int* idx );

 返回值类型占用空间大,也有小的方案 as following:

// Pointer access to matrix structures
uchar* cvPtr1D(
      const CvArr* arr,
      int          idx0,
      int*         type = NULL
);
uchar
* cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type = NULL );
uchar
* cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, int* type = NULL );
uchar
* cvPtrND( const CvArr* arr, int* idx, int* type = NULL, int create_node = 1, unsigned* precalc_hashval = NULL );

 

  • Set Pixel
// Set element functions for CvMat or IplImage.  
void cvSetReal1D( CvArr* arr, int idx0, double value );
void cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );
void cvSetReal3D(
   CvArr* arr,
   int idx0,
   int idx1,
   int idx2,
   double value
);
void cvSetRealND( CvArr* arr, int* idx, double value );
void cvSet1D( CvArr* arr, int idx0, CvScalar value ); void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value ); void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value ); void cvSetND( CvArr* arr, int* idx, CvScalar value );

 

  • 综合性例子
/* License:
   Oct. 3, 2008
   Right to use this code in any way you want without warrenty, support or any guarentee of it working.

   BOOK: It would be nice if you cited it:
   Learning OpenCV: Computer Vision with the OpenCV Library
     by Gary Bradski and Adrian Kaehler
     Published by O'Reilly Media, October 3, 2008
 
   AVAILABLE AT: 
     http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
     Or: http://oreilly.com/catalog/9780596516130/
     ISBN-10: 0596516134 or: ISBN-13: 978-0596516130    

   OTHER OPENCV SITES:
   * The source code is on sourceforge at:
     http://sourceforge.net/projects/opencvlibrary/
   * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
     http://opencvlibrary.sourceforge.net/
   * An active user group is at:
     http://tech.groups.yahoo.com/group/OpenCV/
   * The minutes of weekly OpenCV development meetings are at:
     http://pr.willowgarage.com/wiki/OpenCV
*/

#include <stdio.h>
#include <cv.h>
#include <highgui.h>

float sum( CvMat* mat ) {
  float s = 0.0f;
  for( int row=0; row<mat->height; row++ ) {
    float* ptr = mat->data.fl + row * mat->step/4;
    for( int col=0; col<mat->width; col++ ) {
      s += *ptr++;
    }
  }
  return( s );
};

int main(int argc, char** argv)
{
    CvMat *mat = cvCreateMat(5,5,CV_32FC1);
    float element_3_2 = 7.7;
    *((float*)CV_MAT_ELEM_PTR( *mat, 3,2) ) = element_3_2;
    cvmSet(mat,4,4,0.5000);
    cvSetReal2D(mat,3,3,0.5000);
    float s = sum(mat);
    printf("%f\n",s);
    return 0;
}
View Code

 

posted @ 2016-07-08 12:27  郝壹贰叁  阅读(1008)  评论(0编辑  收藏  举报