[HCI] 04. Mat Class의 이해

조혜정·2021년 10월 7일
1
post-thumbnail

✔ Mat Class 생성자

다양한 종류의 Mat Class 생성자 형태

Mat Class는 OpenCV에서 영상을 담을 때 사용하는 데이터 구조로 다양한 생성자를 제공한다.
(다양한 생성자를 활용하여 다양한 형태의 Mat 객체를 생성 가능)
Code
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
	float data[] = {
		1.2f, 2.3f, 3.2f,
		4.5f, 5.f, 6.5f,
	};

	Mat m1(2, 3, CV_8U); // 채널 미지정시 C1가 default
	Mat m2(2, 3, CV_8U, Scalar(300)); // uchar : 안에 값이 255를 넘을 경우 255로 할
	Mat m3(2, 3, CV_16S, Scalar(300)); // short : 300으로 저장
	Mat m4(2, 3, CV_32F, data); // data 값으로 초기

	Size sz(2, 3); // width = 2, height = 3;
	Mat m5(sz, CV_64F);
	Mat m6(Size(2, 3), CV_32F, data);

	cout << "[m1] = \n" << m1 << endl;
	cout << "[m2] = \n" << m2 << endl;
	cout << "[m3] = \n" << m3 << endl;
	cout << "[m4] = \n" << m4 << endl;
	cout << "\n[m5] = \n" << m5 << endl;
	cout << "[m6] = \n" << m6 << endl;

	waitKey(0);
	return 0;
}
실행 화면
⚠ 간단하게 type 알아보기
Mat(3, 4, CV_8UC3); // Mat::Mat(int rows, int cols, int type)
// CV_ : openCV의 상수 prefix로 CV가 쓰인다. (Constant prefix)
// 8U : 8bit unsigned
// C3 : Channel이 3개 (C1 -> grayScale, C3 -> RGB)
// 따라서, 8비트 unsigned 타입의 3개의 채널을 가진다.
// CV_8U : Mat::depth()로 알 수 있으며 C3 : Mat::channels()를 통해 알 수 있다.

✔ Mat Class 멤버 변수 & 멤버 메소드

Code
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
	Mat m1(4, 3, CV_32FC3);
	cout << "차원 수 : " << m1.dims << "\n";
	cout << "행 개수 : " << m1.rows << "\n";
	cout << "열 개수 : " << m1.cols << "\n";
	cout << "행렬 크기 : " << m1.size() << "\n\n";

	cout << "전체 원소 개수 : " << m1.total() << "\n";
	cout << "한 원소의 크기 : " << m1.elemSize() << "\n";
	cout << "한 원소의 한 채널 크기 : " << m1.elemSize1() << "\n\n";

	cout << "타입 : " << m1.type() << "\n";
	cout << "타입 (채널 수 | 깊이) : " << ((m1.channels() - 1) << 3) + m1.depth() << "\n";
	cout << "깊이 : " << m1.depth() << "\n";
	cout << "채널 : " << m1.channels() << "\n\n";

	cout << "step : " << m1.step << "\n";
	cout << "step1 : " << m1.step1() << "\n";

	waitKey(0);
	return 0;
}
실행 화면

✔ Mat 객체의 자료형 지정 오류 예시

short 2개가 모여서 integer가 되기 때문에 두 개씩 mapping 된다.

✔ 특수한 행렬을 생성하는 함수

Code
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
	Mat m1 = Mat::ones(3, 4, CV_8UC1);
	Mat m2 = Mat::zeros(2, 4, CV_8UC3);
	Mat m3 = Mat::eye(3, 5, CV_8U);

	cout << "[m1] = \n" << m1 << endl;
	cout << "[m2] = \n" << m2 << endl;
	cout << "[m3] = \n" << m3 << endl;

	waitKey(0);
	return 0;
}
실행 화면

✔ Mat 클래스의 할당(=) 연산자

Code
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
	Mat m1(2, 3, CV_8U, 2);
	Mat m2(2, 3, CV_8U, 1);

	m1 = 100;
	Mat m3 = m1 + m2;
	Mat m4 = m1 -2;
	Mat m5 = m1;

	cout << "[m1] = \n" << m1 << endl;
	cout << "[m2] = \n" << m2 << endl;
	cout << "[m3] = \n" << m3 << endl;
	cout << "[m4] = \n" << m4 << endl;
	cout << "[m5] = \n" << m5 << endl;

	m5 = 2;

	cout << "\n[m1] = \n" << m1 << endl;
	cout << "[m5] = \n" << m5 << endl;

	waitKey(0);
	return 0;
}
실행 화면

✔ Mat 객체 복사 : Shallow Copy(얕은 복사) vs Deep Copy(깊은 복사)

Mat A;
A = imread("image.jpg", IMREAD_COLOR); // 메모리 할당

Mat F = A; // 할당 연산자 : 얕은 복사가 수행된다 (메모리를 공유)
Mat B = A.clone(); // clone() : 깊은 복사가 수행된다.
profile
ʜʏᴇᴘᴘʏ ᴅᴇᴠ

0개의 댓글