간략화한 Mat 클래스 정의

class Mat
{
public:
    Mat();
    Mat(int rows, int cols, int type);
    Mat(Size size, int type);
    Mat(int rows, int cols, int type, const Scalar& s);
    Mat(Size size, int type, const Scalar& s);
    Mat(const Mat& m);
    ~Mat();
    // Mat 클래스의 다양한 생성자와 소멸자입니다.

    void create(int rows, int cols, int type);
    bool empty() const;

    Mat clone() const;
    void copyTo(OutputArray m) const;
    Mat& setTo(InputArray value, InputArray mask=noArray());

    static MatExpr zeros(int rows, int cols, int type);
    static MatExpr ones(int rows, int cols, int type);

    Mat& operator = (const Mat& m);
    Mat operator() (const Rect& roi) const;

    template<typename _Tp> _Tp* ptr(int i0 = 0);
    template<typename _Tp> _Tp& at(int row, int col);
    // Mat 클래스의 멤버 함수입니다.
    // Mat 클래스의 멤버 함수에는 연산자 재정의 함수와 정적 멤버 함수도 포함합니다.

    int dims;
    int rows, cols;
    uchar* data;
    MatSize size;
    // Mat 클래스의 주요 멤버 변수입니다.
    ... // 생략
};

행렬의 생성과 초기화

Mat::Mat(int rows, int cols, int type);
  • rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
  • cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
  • type : 새로 만들 행렬의 타입
Mat::Mat(Size size, int type);
  • size : 새로 만들 행렬의 크기. Size(cols, rows) 또는 Size(width, height)
  • type : 새로 만들 행렬의 타입
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 : 행렬 원소 초깃값
static MatExpr Mat::zeros(int rows, int cols, int type);
static MatExpr Mat::zeros(Size size, int type);
  • rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
  • cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
  • size : 새로 만들 행렬의 크기
  • type : 새로 만들 행렬의 타입
  • 반환값 : 모든 원소가 0으로 초기화된 행렬 표현식
static MatExpr Mat::ones(int rows, int cols, int type);
static MatExpr Mat::ones(Size size, int type);
  • rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
  • cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
  • size : 새로 만들 행렬의 크기
  • type : 새로 만들 행렬의 타입
  • 반환값 : 모든 원소가 1로 초기화된 행렬 표현식
static MatExpr Mat::eye(int rows, int cols, int type);
static MatExpr Mat::eye(Size size, int type);
  • rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
  • cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
  • size : 새로 만들 행렬의 크기
  • type : 새로 만들 행렬의 타입
  • 반환값 : 단위 행렬을 표현하는 행렬 표현식
Mat::Mat(int rows, int cols, int type, void *data, size_t step = AUTO_STEP);
Mat::Mat(Size size, int type, void *data, size_t step = AUTO_STEP);
  • rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
  • cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
  • size : 새로 만들 행렬의 크기
  • type : 새로 만들 행렬의 타입
  • data : 사용할 (외부) 행렬 데이터의 주소, 외부 데이터를 사용하여 Mat 객체를 생성할 경우, 생성자에서 원소 데이터 저장을 위한 메모리 공간을 동적으로 할당하지 않습니다.
  • step : (외부) 행렬 데이터에서 한 행이 차지하는 바이트 수, 만약 외부 행렬 데이터의 각 행에 여분의 패딩 바이트(padding byte)가 존재한다면 명시적으로 지정해야 합니다. 만약 기본값 AUTO_STEP을 사용하면 패딩 바이트가 없다고 간주합니다.
void Mat::create(int rows, int cols, int type);
void Mat::create(Size size, int type);
  • rows : 새로 만들 행렬의 행 개수(영상의 세로 크기)
  • cols : 새로 만들 행렬의 열 개수(영상의 가로 크기)
  • size : 새로 만들 행렬의 크기
  • type : 새로 만들 행렬의 타입
Mat& Mat::operator = (const Scalar& s);
  • s : 행렬 원소에 설정할 값
  • 반환값 : 값이 설정된 Mat 객체의 참조
Mat& Mat::setTo(InputArray value, InputArray mask = noArray());
  • value : 행렬 원소에 설정할 값
  • mask : 마스크 행렬, 마스크 행렬의 원소가 0이 아닌 위치에서만 value 값이 설정됩니다. 행렬 전체 원소 값을 설정하려면 noArray() 또는 Mat()을 지정합니다.
  • 반환값 : Mat 객체의 참조

행렬의 복사

Mat Mat::clone() const;
  • 반환값 : *this 행렬의 복사본
void Mat::copyTo(OutputArray m) const;
void Mat::copyTo(OutputArray m, InputArray mask) const;
  • m : 복사본이 저장될 행렬. 만약 *this 행렬과 크기 및 타입이 다르면 메모리를 새로 할당한 후 픽셀 값을 복사합니다.
  • mask : 마스크 행렬. 마스크 행렬의 원소 값이 0이 아닌 좌표에서만 행렬 원소를 복사합니다.
void MatOp2() {
	// 행렬의 다양한 복사 방법
	// 깊은 복사 = Copy Value, 얕은 복사 = Copy Reference
	Mat img1 = imread("gomduri.png");
	
	Mat img2 = img1; // 복사 생성자 (얕은 복사)
	Mat img3;
	img3 = img1; // 대입 연산자 (얕은 복사)

	Mat img4 = img1.clone(); // 깊은 복사
	Mat img5;
	img1.copyTo(img5); // 깊은 복사

	img1.setTo(Scalar(0, 255, 255)); // yellow
	// img1에만 yellow를 적용했지만 img2, img3가 img1의 주소값을 받아온 얕은 복사 이므로
	// img2, img3도 yellow가 출력되는 것을 확인할 수 있다.
	imshow("img1", img1);
	imshow("img2", img2);
	imshow("img3", img3);
	imshow("img4", img4);
	imshow("img5", img5);
	
	waitKey();
	destroyAllWindows();
}

스크린샷(1)

부분 행렬 추출

Mat Mat::operator()(const Rect& roi) const;
Mat Mat::operator()(Range rowRange, Range colRange) const;
  • roi : 사각형 관심 영역
  • rowRange : 관심 행 범위
  • colRange : 관심 열 범위
  • 반환값 : 추출한 부분 행렬 또는 영상. 부분 영상의 픽셀 데이터를 서로 공유합니다.
void MatOp3() {
	// 영상의 부분 영상 반전하기
	Mat img1 = imread("cat.bmp");

	if (img1.empty()) {
		cerr << "Image load failed!" << endl;
		return;
	}

	Mat img2 = img1(Rect(220, 120, 340, 240));
	Mat img3 = img1(Rect(220, 120, 340, 240)).clone();

	img2 = ~img2;

	imshow("img1", img1);
	imshow("img2", img2);
	imshow("img3", img3);

	waitKey();
	destroyAllWindows();
}

스크린샷(2)

Mat Mat::rowRange(int startrow, int endrow) const;
Mat Mat::rowRange(const Range& r) const;
  • startrow : 추출할 행 범위 시작 번호(포함)
  • endrow : 추출할 행 범위 끝 번호(불포함)
  • r : 추출할 행 범위
  • 반환값 : 지정한 행 범위에 해당하는 행렬
Mat Mat::colRange(int startrow, int endrow) const;
Mat Mat::colRange(const Range& r) const;
  • startrow : 추출할 행 범위 시작 번호(포함)
  • endrow : 추출할 행 범위 끝 번호(불포함)
  • r : 추출할 행 범위
  • 반환값 : 지정한 행 범위에 해당하는 행렬
Mat Mat::row(int y) const;
Mat Mat::col(int y) const;
  • y : 부분 행렬로 추출할 행 번호
  • x : 부분 행렬로 추출할 열 번호
  • 반환값 : 추출한 부분 행렬(얕은 복사)

헹렬의 원소 값 참조

template<typename _Tp> _Tp& Mat::at(int y, int x)
  • y : 참조할 행 번호
  • x : 참조할 열 번호
  • 반환값 : (_Tp& 타입으로 형 변환된) y번째 행, x번째 열의 원소 값(참조)
template<typename _Tp>
_Tp* Mat::ptr(int y)
  • y : 참조할 행 번호
  • 반환값 : (_Tp* 타입으로 형 변환된) y번째 행의 시작 주소
void MatOp4() {
	// 행렬의 원소 값 참조 방법을 이용하여 원소 값 증가시키기
	Mat mat1 = Mat::zeros(3, 4, CV_8UC1);

	for (int j = 0; j < mat1.rows; j++) {
		for (int i = 0; i < mat1.cols; i++) {
			mat1.at<uchar>(j, i)++;
		}
	}

	for (int j = 0; j < mat1.rows; j++) {
		uchar* p = mat1.ptr<uchar>(j);
		for (int i = 0; i < mat1.cols; i++) {
			p[i]++;
		}
	}

	for (MatIterator_<uchar>it = mat1.begin<uchar>(); it != mat1.end<uchar>(); ++it) {
		(*it)++;
	}

	cout << "mat1:\n" << mat1 << endl;
}

Microsoft Visual Studio 디버그 콘솔 2022-04-22 오후 5_45_25

행렬 정보 참조하기

    Mat img1 = imread("gomduri.png");
	cout << "Width: " << img1.cols << endl;
	cout << "Height: " << img1.rows << endl;

Microsoft Visual Studio 디버그 콘솔 2022-04-22 오후 5_47_36

  • gomduri.png file의 행렬 정보를 확인할 수 있습니다.
int Mat::channels() const;
  • 행렬의 채널 수를 반환합니다.
int Mat::depth() const;
  • 행렬의 깊이를 반환합니다. (예) CV_8U, CV_32F
size_t Mat::elemSize() const;
  • 한 개의 원소가 차지하는 메모리 크기를 바이트 단위로 반환합니다.
    (CV_32SC3 타입 행렬의 경우 4*3=12를 반환).
size_t Mat::elemSize1() const;
  • 하나의 채널에서 한 개의 원소가 차지하는 메모리 크기를 바이트 단위로 반환합니다.
    (CV_32SC3 타입 행렬의 경우 4를 반환).
bool Mat::empty() const;
  • 비어있는 행렬이면 true를 반환합니다.
bool Mat::isContinuous() const;
  • 각 행의 원소가 연속적으로 저장되어 있으면 true를 반환합니다.
bool Mat::isSubMatrix() const;
  • 행렬이 다른 행렬의 부분 행렬이면 true를 반환합니다.
Size Mat::size() const;
  • 행렬 크기를 Size 타입으로 반환합니다.
size_t Mat::total() const;
  • 전체 원소 개수를 반환합니다.
int Mat::type() const;
  • 행렬의 타입을 반환합니다. (예) CV_32FC1, CV_8UC3
static lnline
std::ostream& operator << (std::ostream& out, const Mat& mtx)
  • out : C++ 표준 출력 스트림 객체
  • mtx : 출력할 행렬
  • 반환값 : C++ 표준 출력 스트림 객체의 참조

일단 여기까지.. 미완성!!

댓글남기기