'CvMat'에 해당되는 글 1건

  1. 2013.01.04 OpenCV의 기본 데이터타입

OpenCV는 자체적인 기본데이터 타입을 가지고있다. OpenCV에서 새로 정의한 구조체 형식의 데이터 타입을 의미하는데 이러한 구조체 타입들은 OpenCV에서 기본단위로 사용된다.

※ opencv/build/include/opencv2/core/types_c.h 파일에서 확인할수 있다.


CvPoint 타입

 typedef struct CvPoint

{

    int x;

    int y;

}

CvPoint;  

※ types_c.h에 정의되어있는 CyPoint 타입

CvPoint는 두개의 정수형 맴버x와 y를 가지고 있는 간단한 구조체이다. OpenCV에서는 CvPoint와 유사한 데이터 타입이 두개 더 정의도어있는데 CvPoint2D32fCvPoint3D32f가 그것이다. CvPoint2D32f타입은 실수형 맴버x와 y를 가지고있다. 그리고 CvPoint3D32f는 깊이정보를 나타내는 실수형 맴버 z를 가지고있다.



CvSize 타입

 typedef struct CvPoint

{

    int x;

    int y;

}

CvPoint;  

CvSize타입은 정수형맴버 width와 height를 가지고있다. 실수형 맴버를 사용하고 싶을때는 CvSize대신 CvSize2D32f데이터 타입을 사용한다.


CvRect 타입

typedef struct CvRect

{

    int x;

    int y;

    int width;

    int height;

}

CvRect;

CvRectCvPointCvSize의 맴버들이 합쳐진 형태의 데이터 타입으로서 네개의 정수형 맴버 x, y, width, height를 가지고있다.


CvScalar 타입

typedef struct CvScalar

{

    double val[4];

}

CvScalar; 

4개의 double형 실수값을 배열 형태로 가지고있다. CvScalar타입을 이용하여 1차원, 2차원 또는 3차원 실수 백터를 표현할 수 있다. 


IplImage 타입

IplImage타입은 흔히 '영상'이라고 부르는 것을 표현하는 데이터 타입이다. 이 타입은 그레이스케일 영상을 표현할 수도 있고, 컬러영상, 또는 4개채널(RGB+알파)를 갖고있는 영상도 표현할 수 있다.


CvMat 행렬구조체 

OpenCV는 C로 구현되었지만 CvMat과 IplImage데이터 타입은 C++에서 볼수 있는 상속 관계를 따르고있다. IplImage는 모든 경우에 대해서 CvMat으로부터 상속받은 것처럼 사용될 수 있다. 

 typedef struct CvMat

{

    int type;

    int step;

 

    /* for internal use only */

    int* refcount;

    int hdr_refcount;

 

    union

    {

        uchar* ptr;

        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;



 CvMat* cvCreateMat(int rows, int cols, int type);

2차원행렬을 만드는 함수는 위와 같다. 세번째 인자 type은 CV_<비트수>(S|U|F)C<채널 개수> 형태의 다양한 데이터타입을 지정할 수 있다.

ex) CV_32FC1(32비트 실수형 1체널), CV_32FC3, CV_32SC2


int cvGetElemType(const CvArr* arr);

int cvGetDims(const CvArr* arr, int* sizes=NULL);

int cvGetDimSize(const CvArr* arr, int index); 

cvGetElementType() : 행렬의 원소타입을 나타내는 정수값(CV_8UC1, CV_64FC4)을 반환한다.

cvGetDims() : 행렬의 포인터와 선택적으로 정수형 배열주소를 인자로 받고 행렬의 차수를 반환한다.

cvGetDimSize() : 함수의 두번째 인자에 알고싶은 차원의 인덱스를 넘겨주면 해당 차원의 크기를 반환한다.


행렬 데이터에 접근

1) 간편한방법(CV_MAT_ELEM, CV_MAT_ELEM_PTR) : 1차원 혹은 2차원 행렬을 다룰때 적합하다.

CV_MAT_ELEM() 메크로를 사용한다. 이 메크로는 행렬과 원소의 타입, 그리고 행과 열을 입력받아 해당 원소의 값을 반환한다.

ex) float element=CV_MAT_ELEM(rotmat, float, 2, 3);   //행렬의 2, 3열에 있는 데이터를 가져옴

만약 단순히 값을 읽어오는 것이 아니라 값을 설정하고 싶은 경우 라면 CV_MAT_ELEM_PTR() 매크로를 사용한다ㅣ

ex) *((float *)CV_MAT_ELEM_PTR(rotmat, 1, 1)) = 7.7f; //행렬의 (1, 1) 값을 7.7 변경


2) 엄격한 방법

행렬 데이터에 접근하는 포인터 반환함수를 사용한다 (cvPtr*D 또는 cvGet*D)

행렬에 데이터를 설정하는 함수로는 cvSet*D형태의 함수가 있다.


3) 적절한 방법

 //3채널 행렬의 모든 원소값의 합을 구하는 함수

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

};


※ CvMat구조체의 step 맴버변수

step 원소는 행열의 행 크기를 바이트 단위로 나타낸다. 따라서 다음행르로 이동하기 위해서 해당 포인터에 stop크기 만큼 더해줘야한다. 만약 행렬이 정수형 또는 실수형이고, 이행렬의 데이터를 가리키는 int또는 float타입의 포인터를 가지고 있을 경우 다음행으로 이동하기 위해 step/4(double타입이라면 stop/8) 크기만큼 더해줘야 한다.



CvArr 타입

CvArr 데이터 타입은 CvMat의 추상클래스 역할을 한다.


IplImage 구조체

IplImage구조체는 본질적으로 CvMat와 동일하지만, 영상을 표현하기에 적합한 추가 항목들을 가지고있다. 

 typedef struct _IplImage

{

    int  nSize;             /* sizeof(IplImage) */

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

    int  nChannels;         /* 1~4까지의 값을 갖는다. OpenCV의 IplImage는 체널의 개수를 개별적으로 처리 */

    int  alphaChannel;      /* Ignored by OpenCV */

    int  depth;             /* OpenCV의 IplImage는 데이터타입(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;         /* IPL_DATA_ORDER_PIXEL (0) - 각 픽셀은 다중체널값을 차례대로 가지고있다. (인터리브 방식),

                               IPL_DATA_ORDER_PLANE (1) - 각 채널별로 따로 픽셀값이 저장된다.

                               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;        /* 영상 데이터의 시작주소         */

    int  widthStep;         /* 한행이 실제로 차지하고 있는 바이트 수(step과 유사) */

    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;





Posted by No names
,