본문 바로가기

컴퓨터 비전 study

OpenCV Mat 클래스(1)

1.1 Mat 클래스

: OpenCV에서 가장 많이 사용하며, 고차원 행렬을 표현할 수 있고 한 개 이상의 채널을 가질 수 있다.

정수,실수,복소수 등으로 구성된 행렬 또는 벡터 / 그레이 스케일 / 컬러 영상 / 벡터필드, 포인트 클라우드, 텐서, 히스토그램 등의 정보 를 저장할 수 있다. 

> But, 2차원 영상 데이터를 저장하고 처리하는 용도로 가장 많이 쓰인다. 

 

Mat::dims                > Mat 행렬의 차원 (영상과 같은 2차원 행렬의 dims = 2)

  >int dims;

Mat::rows , Mat::cols   > 2차원 행렬의 크기(rows 는 행 개수=세로 픽셀크기, cols 는 열 개수=가로 픽셀크기)

                             > 2차원 행렬에서만 의미있는 값을 가지며, 3차원 이상의 행렬에서는 -1이 저장된다.

                                3차원 이상의 행렬의 크기는 Mat::size 변수를 이용하여 참조할 수 있다.

  > int rows, cols;      /   > MatSize size;

Mat::data                 > 행렬의 원소 데이터가 저장되어 있는 메모리 공간을 가리키는 포인터형 멤버 변수

                                행렬에 아무것도 저장되어 있지 않다면 0(NULL)값을 가진다.

  > uchar* data;

 

* 이외의 멤버 변수들은 활용성이 높지 않으므로 생략

* OpenCV는 unsigned char, signed char, unsigned short, signed short, int, float, double 자료형을 사용하는 Mat 행렬 지원

 

schar 부호있는 1바이트 정수

uchar 부호없는 1바이트 정수 (=unsigned char를 재정의한 이름)

short 부호있는 2바이트 정수(C/C++기본자료형)

ushort 부호없는 2바이트 정수

int 부호있는 4바이트 정수(C/C++기본자료형)

uint 부호없는 4바이트 정수

int64 부호있는 8바이트 정수

uint64 부호없는 8바이트 정수

float64_t (부호있는)2바이트 실수

float (부호있는)4바이트 실수(C/C++기본자료형)

double (부호있는)8바이트 실수(C/C++기본자료형)

 

깊이(Depth) : 행렬이 어떤 자료형을 사용하는지에 대한 정보

>CV_<bit-depth>{U|S|F}

U는 부호없는 정수형, S는 부호있는 정수형, F는 부동 소수형 의미

ex. #define CV_8U   0 -> uchar, unsigned char  <unsigned char 자료형을 사용한다는 의미

    #define CV_32F   5  -> float  >행렬의 원소를 float 자료형으로 표현하려면 깊이가 CV_32F인 행렬을 사용해야한다. 

 

채널(channel) : Mat 행렬 원소를 구성하는 각각의 값    > 하나의 채널을 가질 수도, 여러 개의 채널을 가질 수도 있다.

 하나의 행렬을 구성하는 각 채널은 모두 같은 자료형을 사용해야 한다.

 ex. 그레이 스케일 영상 > 하나의 픽셀이 밝기정보 하나만 사용 > 1채널 행렬

      트루컬러 영상 > 하나의 픽셀이 파란색(B), 녹색(G), 빨간색(R) 세 개의 색상 정보를 가지고 있으므로 3채널 행렬

 

타입(type) : Mat 행렬의 깊이 정보와 채널 수 정보를 합친 것

>CV_<bit-depth>{U|S|F}C(<number of channels>)

 ex. CV_8UC1  - 8비트 unsigned char 자료형을 사용하고 채널이 한 개인 행렬또는 영상을 의미한다. 다만, 채널이 한 개 인경우 C1은 생략할 수 있다.

  R,G,B 세 개의 색상 성분을 가지고 있는 컬러영상은 unsigned char 자료형을 사용하고 세개의 채널을 갖고있으므로 CV_8UC3타입 / 복소수처럼 두개의 실수 성분을 사용하는 행렬 = CV_32FC2 타입

 

1.2 행렬의 생성과 초기화

Mat 객체 생성 방법 

1) Mat 클래스의 기본 생성자 이용

> Mat img1;

  > 비어있는 행렬 

> Mat::Mat(int rows, int cols, int type);

 rows   새로만들 행렬의 행 개수(영상의 세로크기)

 cols    새로만들 행렬의 열 개수(영상의 가로크기)

 type    새로만들 행렬의 타입

Mat img2(480,640, CV_8UC1);     // unsgined char , 1-channel    -> 순서가 세로크기,가로크기인 점 주의

 -> 그레이 스케일 영상에서 주로 사용함.

 

2) Size 클래스 이용

Mat::Mat(Size size, int type);

size 새로 만들 행렬의 크기, Size(cols,rows) or Size(Width, height)

type 새로 만들 행렬의 타입

> Mat img4(Size(640,480), CV_8UC3);     // Size(width,height)    -> 위의 방법과 다르게 가로크기,세로크기 순서

-> 가로 640, 세로 480인 3채널 컬러영상

 

Mat 객체의 행렬의 크기와 타입만 지정할 경우 모든 원소는 임의의 값으로 채워지므로 모든 원소값을 초기화하는게 안전

> Mat::Mat(int rows, int cols, int type, const Scalar& s);

> Mat::Mat(Size size, int type, const Scalar& s);

s 행렬 원소 초깃값

Scalar 클래스는 네 개의 실수값을 저장할 수 있는 OpenCV클래스이며, 주로 영상의 픽셀 값을 표현하는 용도로 사용

> Mat img5(480,640,CV_8UC1,Scalar(128));    // 그레이스케일 영상 img5의 모든 픽셀 밝기가 128로 설정된다

Scalar 클래스를 이용하여 컬러 영상의 색상을 지정할때에는 (B,G,R) 순서대로 값을 지정한다.

 

행렬 생성 시 모든 원소 값을 0으로 초기화하는 방법

1. Mat 클래스의 행렬 원소 초깃값에 Scalar(0)을 지정

2. Mat::zeros() 함수를 이용하여 모든 원소가 0으로 초기화된 행렬 생성

 

static MatExpr Mat::zeros(int rows, int cols, int type);

static MatExpr Mat::zeros(sSize size, int type);

-> 반환값 : 모든 원소가 0으로 초기화된 행렬 표현식 / zeros() 함수는 Mat 클래스의 정적멤버 함수이기에 실제코드에서 Mat::를 붙여서 사용해야한다. zeros()함수의 반환형인 MatExpr은 행렬의 대수 연산을 표현하는 클래스이며 자동으로 Mat클래스 형으로 변환된다.

 

모든원소가 1로 초기화된 행렬 표현식은 위와 같은 방법으로 static MatExpr Mat::ones() 함수를 사용한다.

단위 행렬 표현식 또한, static MatExpr Mat::eye() 함수를 사용한다.

 

Mat 객체를 생성할때, 기존에 이미 할당되어 있는 메모리 공간의 데이터를 행렬 원소값으로 사용할 수 있으며, 자체적인 메모리 할당을 수행하지 않고 외부 메모리를 참조하는 방식이기에 객체 생성이 빠르다는 장점이 있다.

 

Mat::Mat(int rows,int cols, int type, void*data, size_t step=AUTO_STEP);

data : 외부 행렬 데이터의 주소

step : 외부 행렬 데이터에서 한 행이 차지하는 바이트 수, 기본값을 사용한다면 패딩 바이트가 없다고 간주

 

비어있는 Mat 객체 또는 이미 생성된 Mat 객체에 새로운 행렬을 할당하려면 Mat::create() 함수 사용

void Mat::create(int rows, int cols, int type);

void Mat::create(Size size, int type);

 

하지만 Mat::create() 함수는 초기화 기능이 없으므로 별도의 함수를 이용해야한다.

 =연산자 재정의 또는 Mat::setTo()멤버 함수를 이용하여 전체 원소값을 한번에 설정할 수 있다.

Mat& Mat::operator=(const Scalar&s);

s:원소에 설정할 값

 

Mat& Mat::setTo(InputArray value, InputArray mask=noArray());

value : 행렬 원소에 설정할 값

mask : 마스크 행렬, 마스크 행렬의 원소가 0이 아닌 위치에서만 value 값 설정, 전체 원소값 설정하려면 noArray 또는 Mat 지정

 

 

'컴퓨터 비전 study' 카테고리의 다른 글

Open CV Vec와 Scalar 클래스  (0) 2020.02.26
OpenCv Mat 클래스(3)  (0) 2020.02.26
Open CV Mat 클래스(2)  (0) 2020.02.19
OpenCV 기본 자료형 클래스  (0) 2020.02.14
Open CV 개요와 기초 사용법  (0) 2020.02.14