7. Mat
OpenCV에서 가장 많이 사용하는 클래스
행렬을 나타내는 클래스(실제로 2차원 영상을 표현하는 용도로 많이 사용)
멤버 변수
Mat::dims
Mat 행렬의 차원을 나타냄(2차원일 경우 값은 2)
Mat::rows
Mat::cols
행렬의 행 개수, 열 개수를 나타냄
(영상의 세로 픽셀 크기, 가로 픽셀 크기)
(2차원 행렬인 경우에만 의미 있는 값을 가지며 3차원 이상의 행렬에서는 -1)
Mat::size
3차원 이상의 행렬의 크기 정보
Mat::data
행렬의 원소 데이터가 저장되어 있는 메모리 공간을 가리키는 포인터형 멤버 변수
행렬의 생성과 초기화
Mat img1;
기본 생성자를 사용한 변수 선언(비어 있는 행렬 생성)
Mat img2(480, 640, CV_8UC1);
가로 640, 세로 480, 1채널(그레이스케일)의 unsigned char형 행렬 생성
Mat img3(480, 640, CV_8UC3);
가로 640, 세로 480, 3채널(트루컬러)의 unsigned char형 행렬 생성
Mat img4(Size(640, 480), CV_8UC3);
Size 클래스 이용, 가로 640, 세로 480, 3채널의 unsigned char형 행렬 생성
위와 같은 방식은 행렬의 값이 정해지지 않기 때문에 쓰레기 값이 들어감, 다음과 같은 방식으로 값을 정해줄 수 있음
Mat img5(480, 640, CV_8UC1, Scalar(128));
밝기 128
Mat img6(Size(640, 480), CV_8UC3, Scalar(0, 0, 255));
red 칼라
새로운 행렬을 생성할 때 모든 원소 값을 0으로 초기화하는 경우가 많으며 이런 경우에 사용하기 위한 별도의 함수존재
Mat mat1 = Mat::zeros(3, 3, CV_32SC1);
1로 초기화
Mat mat2 = Mat::ones(3, 3, CV_32FC1);
단위 행렬
Mat mat3 = Mat::eye(3, 3, CV_32FC1);
Mat 객체를 생성할 때, 행렬 원소를 저장할 메모리 공간을 새로 할당하는 것이 아니라 기존에 이미 할당되어 있는 메모리 공간의 데이터를 행렬 원소 값으로 사용할 수 있다.
float data[] = { 1, 2, 3, 4, 5, 6 };
Mat mat4(2, 3, CV_32FC1, data);
외부 메모리 공간을 활용하여 Mat 객체를 생성한다는 것은 자체적인 메모리 할당을 수행하지 않고 외부 메모리를 참조하는 방식이기 때문에 객체 생성이 빠르다는 장점이 있다.
또한, 외부 배열을 행렬 원소 값으로 사용하고자 할 경우 외부 배열 크기와 생성할 행렬 원소 개수는 같아야 하고 서로 사용하는 자료형도 같아야 한다.
동적 할당하여 만든 대용량 메모리도 Mat 클래스에 참조하여 사용 가능, 다만 동적 할당한 메모리는 Mat 객체가 소멸될 때 자동으로 해제되지 않으므로 반드시 사용자가 직접 메모리를 해제해야 한다.
Mat_ 클래스 사용 Mat 객체 생성
Mat_<float> mat5_(2, 3);
mat5_ << 1, 2, 3, 4, 5, 6;
Mat mat5 = mat5_;
다음과 같이 한줄로도 사용가능
Mat mat5 = (Mat_<float>(2, 3) << 1, 2, 3, 4, 5, 6);
초기화 리스트를 이용한 행렬 초기화 방법
Mat mat6 = Mat_<float>({2, 3}, { 1, 2, 3, 4, 5, 6 });
비어 있는 Mat 객체 또는 이미 생성된 Mat 객체에 새로운 행렬을 할당하려면 Mat 클래스의 Mat::create() 사용
mat4.create(256 ,256, CV_8UC3);
mat5.create(4, 4, CV_32FC1);
새로 만들 행렬의 크기 또는 타입이 기존 행렬과 다른 경우, 기존 메모리 공간을 해제한 후 새로운 행렬 데이터 저장을 위한 메모리 공간 할당
Mat::create() 함수는 새로 만든 행렬의 원소 값을 초기화하는 기능이 없기 때문에 행렬을 생성한 후 행렬 전체 원소 값을 초기화하고 싶다면 Mat::setTo() 멤버 함수 또는 = 연산자 재정의를 이용해야한다.
mat4 = Scalar(255, 0, 0);
mat5.setTo(1.f);