Mat 클래스를 이용하여 객체의 생성과 초기화 방법은 여러가지 방법이 있다.
Mat 클래스의 객체 생성 방법
Mat();
기본 생성자
Mat img1;
가장 기본적인 Mat 객체 생성 방법으로 Mat 클래스의 기본 생성자를 이용하는 방법이다.
기본 생성자는 아무런 인자를 받지 않으며, 실제 코드 작성 시에는 단순히 Mat 클래스 타입의 변수를 선언하는 형태이다.
img1 객체는 비어 있는 행렬이다. 즉 img1.rows 와 img1.cols 의 값은 0이고 img1.data에도 0(NULL)이 저장된다.
이렇게 비어 있는 행렬을 OpenCV 영상 처리 함수의 입력으로 사용하거나 비어 있는
행렬의 원소 값을 참조 시 에러가 발생한다.
Mat::Mat();
객체 생성과 동시에 원소 값 저장을 위한 메모리 공간 할당하는 생성자
Mat::Mat(int rows, int cols, int type);
rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
type : 새로 만들 행렬의 타입
이 생성자는 행 개수가 rows 이고, 열 개수가 cols인 2차원 행렬(또는 영상)을 생성한다.
3번 째 인자 type에는 Mat 객체의 타입을 나타내는 매크로 상수를 전달한다.
Mat img2(480, 640, CV_8UC1); // 가로480 x 세로640, unsigned char, 1-Channel
Mat img3(480, 640, CV_8UC3); // 가로480 x 세로640, unsigned char, 3-Channels
가로 크기가 640이고, 세로 크기 480인 영상을 생성하는 코드이다.
주의해야 할 점은 영상의 크기 정보를 지정할 때 세로 - 가로 크기 순서이다.
img2와 img3의 크기는 지만, 타입이 다른 영상이다.
img2 객체는 unsigned char 자료형을 사용하면서 1개의 채널이 있는 영상을 표현한다.
즉, 그레이스케일 영상에서 사용한다.
img3 객체는 unsigned char 자료형을 사용하면서 3개의 채널이 있는 영상을 표현한다.
즉, 트루컬러 영상에서 사용한다.
Mat::Mat();
행렬의 크기를 지정하는 생성자
Mat::Mat(Size size, int type);
size : 새로 만들 행렬의 크기. Size(cols, rows) or Size(width, height)
type : 새로 만들 행렬의 타입
여기서 사용된 Size 클래스는 2차원 사각형(또는 영상이나 행렬)의 가로,
세로 크기를 표현하기 위해 사용하는 OpenCV 클래스다.
Size 클래스의 생성자는 보통 2개의 인자를 받으며, 가로, 세로 크기의 순으로 값을 지정한다.
Mat img4(Size(640, 480), CV_8UC3);
가로640 x 세로480 크기의 3채널 컬러 영상을 생성하는 코드이다.
이처럼 행렬의 크기와 타입을 지정하여 Mat 객체를 생성할 경우,
Mat 행렬의 모든 원소는 쓰레기 값(임의의 값)으로 채워진다.
그러므로 Mat 객체를 생성과 동시에 모든 원소 값을 특정 값으로 초기화하여 사용해야 한다.
Mat::Mat();
정해진 크기와 타입의 Mat 객체를 생성하고 모든 원소 값을 초기화하는 생성자
Mat::Mat(int rows, int cols, int type, const Scalar& s);
Mat::Mat(Size size, int type, const Scalar& s);
rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
size : 새로 만들 행렬의 크기
type : 새로 만들 행렬의 타입
s : 행렬 원소 초기 값
이 생성자들은 행렬의 크기와 타입을 지정하는 생성자에 원소의 초깃값을 설정할 수 있는 인자 s가 추가되어 있다.
초깃값 s의 타입으로 사용된 Scalar 클래스는 4개의 실수 값을 저장할 수 있는 OpenCV의 클래스이다.
주로 영상의 픽셀 값을 표현하는 용도로 사용되고, Scalar 클래스가 그레이스케일 영상의 픽셀 값을 표현할 때 하나의 멤버 변수만 사용하고, 3채널 컬러 영상의 픽셀 값을 표현할 때에는 3개의 멤버 변수를 사용한다.
Mat img5(480, 640, CV_8UC1, Scalar(128));
Mat img6(480, 640, CV_8UC3, Scalar(0, 0, 255)); // Red
img5는 모든 픽셀 값이 128로 초기화된 그레이스케일 영상 생성 방법이고,
img6은 모든 픽셀이 빨간색으로 설정된 컬러 영상 생성 방법이다.
Mat::Mat();
Mat 객체 생성 시 기존 메모리 공간의 데이터를 행렬 원소의 값으로 사용하는 생성자
Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
Mat::Mat(Size size, int type, void* data, step=AUTO_STEP);
rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
size : 새로 만들 행렬의 크기
type : 새로 만들 행렬의 타입
data : 사용할 (외부) 행렬 데이터의 주소. 외부 데이터를 사용하여 Mat 객체를 생성할 경우,
생성자에서 원소 데이터 저장을 위한 메모리 공간을 동적으로 할당하지 않는다.
step : (외부( 행렬 데이터에서 한 행이 차지하는 바이트 수.
외부 행렬 데이터의 각 행에 여분의 패딩 바이트(Padding byte)가 존재한다면, 명시적으로 지정해야 한다.
만약 기본값 AUTO_STEP 사용 시 패딩바이트가 없다고 간주한다.
Mat 객체를 생성할 때, 행렬 원소를 저장할 메모리 공간을 새로 할당하는 것이 아니라 기존에 이미 할당되어 있는
메모리 공간의 데이터를 행렬 원소 값으로 사용할 수 있다.
외부 메모리 공간을 활용하여 Mat 객체를 생성한다는 것은 자체적인 메모리 할당을 수행하지 않고
외부 메모리를 참조하는 방식이기 때문에 객체 생성이 빠르다는 장점이 있다.
float data[] = { 1, 2, 3, 4, 5, 6 };
Mat mat4(2, 3, CV_32FC1, data);
외부 메모리 공간의 주소를 지정하는 Mat 클래스의 생성자이다.
외부 배열을 행렬 원소 값으로 사용하고자 할 경우, 외부 배열 크기와 생성할 행렬 원소 개수, 자료형은 같아야 한다.
data 배열은 6개의 원소를 가지고 있고, mat4도 2행 3열이므로 6개의 원소로 서로 원소의 개수가 같다.
또한 모두 float 형이다.
외부 메모리 공간을 참조하여 Mat 객체를 생성할 경우, Mat 객체의 원소 값과 외부 메모리 공간의 데이터 값이
상호 공유된다. mat4 객체를 생성한 후 외부 메모리 공간의 값을 변경하면, mat4 행렬의 원소 값도 같이 변경된다.
반대로 행렬의 원소 값을 변경하면 외부 메모리 공간의 값도 변경된다.
이는 하나의 메모리 공간을 서로 공유하기 때문이다.
동적 할당하여 만든 대용량 메모리도 Mat 클래스에서 참조하여 사용할 수 있으나,
사용자가 반드시 메모리를 해제해야 한다.
Mat 객체가 소멸될 때 자동으로 해지되지 않는다.
사용자가 지정한 원소 값을 이용하여 Mat 객체를 생성할 수 있다.
Mat_ 클래스 : Mat 클래스를 상속하여 만든 템플릿 클래스로서 Mat_ 클래스 객체와 Mat 객체는 상호 변환이 가능하다.
Mat_ 클래스는 << 연산자와 콤마(,)를 이용하여 간단하게 행렬 원소 값을 설정하는 인터페이스를 제공한다.
Mat_<float> mat5_(2, 3);
mat5_ << 1, 2, 3, 4, 5, 6;
Mat mat5 = mat5_;
Mat_객체를 만든 후 << 연산자로 행렬 원소를 지정하고 이를 Mat 객체로 변환하여 사용할 수 있다.
mat5_는 float 자료형을 사용하는 2 x 3 행렬이다.
Mat_ 클래스는 템플릿 클래스로 정의되어 있어서 저장할 원소의 자료형을 지정해주어야 한다.
Mat::zeros();
행렬 원소가 0으로 초기화된 행렬을 생성하는 함수
static MatExpr Mat::zeros(int rows, int cols, int type);
static MatExpr Mat::zeros(Size size, int type);
rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
size : 새로 만들 행렬의 크기
type : 새로 만들 행렬의 타입
반환값 : 모든 원소가 0으로 초기화된 행렬 표현식
새로운 행렬을 생성할 때 모든 원소 값을 0으로 초기화하는 경우가 많은데, 이런 경우에 사용한다.
Mat::zeros() 함수는 새로 생성할 행렬의 크기와 타입 정보 인자를 받는다.
Mat::zeros() 함수는 Mat 클래스의 정적 멤버 함수이기 때문에 실제 코드에서 Mat:: 을 붙여서 사용해야 한다.
반환형인 MatExpr은 OpenCV에서 행렬의 대수 연산을 표현하는 클래스이며, 자동으로 Mat 클래스로 형 변환된다.
그러므로 Mat::zeros() 함수의 반환 값은 Mat 타입의 변수에 할당할 수 있다.
Mat mat1 = Mat::zeros(3, 3, CV_32SC1);
3 x 3 정수형 행렬을 생성하면서, 0으로 초기화된 mat1을 생성하는 방법이다.
Mat::ones();
행렬의 모든 원소가 1로 초기화된 행렬을 생성하는 함수
static MatExpr Mat::ones(int rows, int cols, int type);
static MatExpr Mat::ones(Size size, int type);
rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
size : 새로 만들 행렬의 크기
type : 새로 만들 행렬의 타입
반환값 : 모든 원소가 1으로 초기화된 행렬 표현식
함수의 사용법은 Mat::zeros와 완전히 같으며, 생성되는 행렬 원소의 초깃값만 다르다.
Mat::eye();
행렬의 원소가 단위 행렬로 생성되는 함수
static MatExpr Mat::eye(int rows, int cols, int type);
static MatExpr Mat::eye(Size size, int type);
rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
size : 새로 만들 행렬의 크기
type : 새로 만들 행렬의 타입
반환값 : 모든 원소가 0으로 초기화된 행렬 표현식
함수의 사용법은 Mat::zeros와 완전히 같으며, 생성되는 행렬 원소의 초깃값만 다르다
Mat::create();
비어 있는 Mat 객체 또는 이미 생성된 Mat 객체에 새로운 행렬을 할당하는 함수
void Mat::create(int rows, int cols, int type);
void Mat::create(Size size, int type);
rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
size : 새로 만들 행렬의 크기
type : 새로 만들 행렬의 타입
이미 행렬 데이터가 할당되어 있는 Mat 객체에서 Mat::create() 함수를 호출하거나,
Mat::create() 함수의 인자로 지정한 행렬 크기와 탕비이 기존 행렬과 모두 같으면
Mat::create() 함수는 동작을 하지 않고, 그대로 함수를 종료한다.
새로 만든 행렬의 크기 또는 타입이 기존 행렬과 다를 경우, Mat::create() 함수는 기존 메모리 공간을 해제한 후
새로운 행렬 데이터 저장을 위한 메모리 공간을 할당한다.
mat4.create(256, 256, CV_8UC3);
mat5.create(4, 4, CV_32FC1);
이미 생성되어 있는 Mat 클래스 타입의 변수 mat4, mat5에 새로운 크기와 타입의 행렬을 할당하는 코드이다.
Mat::create() 함수는 새로 만든 행렬의 원소 값을 초기화하는 기능이 없으므로 별도의 함수를 사용해야 한다.
Mat 클래스는 =연산자 재정의 또는 Mat::setTo 멤버 함수를 사용해야 한다.
Mat::setTo();
Mat 행렬의 전체 원소 값 설정을 위한 함수
Mat& Mat::setTo(InputArray value, InputArray mask = noArray());
value : 행렬 원소에 설정한 값
mask : 마스크 행렬. 마스크 행렬의 원소가 0이 아닌 위치에서만 value 값이 설정된다.
행렬 전체 원소 값을 설정하려면 noArray() 또는 Mat()을 지정한다.
반환값 : Mat 객체와 참조
mat4 = Scalar(255, 0, 0);
mat5.setTo(1, f);
위 코드는 mat4 영상의 모든 픽셀을 파란색에 해당하는 Scalar(255, 0, 0)으로 설정하고,
행렬 mat5의 모든 원소 값은 1.f로 설정하는 코드이다.
Mat::operator();
행렬의 원소 값 설정을 위한 연산자
Mat& Mat::operator = (const Scalar& s);
s : 행렬 원소에 설정할 값
반환값 : 값이 설정된 Mat 객체의 참조
'DevelopmentTool > OpenCV' 카테고리의 다른 글
[OpenCV] Mat 클래스 ROI 추출 함수 (0) | 2022.11.17 |
---|---|
[OpenCV] Mat 클래스의 행렬 복사 (0) | 2022.11.17 |
[OpenCV] Mat 클래스의 자료형 (1) | 2022.11.17 |
[OpenCV] Mat 클래스 (1) | 2022.11.17 |
[OpenCV] String 클래스 (0) | 2022.11.17 |