[OpenCV] Mat 클래스 – 2. 초기화, 복사(얕은 복사, 깊은 복사), ROI

[OpenCV] Mat 클래스 – 2. 초기화, 복사(얕은 복사, 깊은 복사), ROI

이번 글에서는 저번 글에 이어서 초기화와, 복사, Region of Interest(ROI)에 대해 알아보겠습니다.

초기화

초기화 알아보겠습니다.
ones는 모든 원소를 1로 초기화하는 함수이고, eye는 대각선을 1로 저장합니다.

// 행, 열, 타입
MatExpr ones(int rows, int cols, int type);
// ex
Mat img = Mat::ones( 3, 3, CV_8UC1 );

// 행, 렬, 타입
MatExpr eye(int rows, int cols, int type);
// ex
Mat img = Mat::eye( 3, 3, CV_8UC1 );

이미지로는 아래 그림을 참고하시면 됩니다.

Mat을 생성할 때는 아래와 같이 배열을 이용하여 사용할 수 있습니다.

unsigned char aucData[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Mat img = Mat( 3, 3, CV_8UC1, aucData );

얕은 복사, 깊은 복사

Mat 클래스의 복사에 대해 알아보겠습니다.

복사에는 2가지 종류가 있습니다. 얕은 복사는 복사 하는 쪽과 받는 쪽이 같은 원소를 공유합니다.

Mat src = Mat( 3, 3, CV_8UC1 );
// case 1
Mat paste1 = src; // 얕은 복사

// case2
Mat paste2;
paste2 = src; // 얕은 복사

위 코드에서 src의 행렬 원소값이 변경되면 paste에서도 변경 됩니다.

깊은 복사는 복사 하는쪽과 받는쪽이 다른 객체로 생성됩니다.

Mat src = Mat( 3, 3, CV_8UC1 );
// case 1
Mat paste1 = src.clone(); // 깊은 복사

// case 2
Mat paste2;
src.copyTo( paste2 ); // 깊은 복사

clone과 copyTo 함수를 사용하면 크기가 같고 원소 값이 같은 깊은 복사를 수행합니다.

ROI

마지막으로 부분 영상 추출을 해보겠습니다.

아래와 같이 코드를 구현하시면 부분 영상을 추출할 수 있습니다.

Mat src = imread("mountain.jpg", IMREAD_COLOR);
Mat ROI = src( Rect( 100, 100, 100, 100 ) ); // 얕은 복사
// Mat ROI = src( Rect( 100, 100, 100, 100 ) ).clone(); // 깊은 복사는 뒤에 .clone()을 붙이면 된다.

imshow( "src", src );
imshow( "ROI", ROI );

이미지로 보자면 아래 이미지에서 빨간 부분이 ROI(Region of Interest)와 같습니다.

ROI를 반전을 수행하면 src와 ROI는 아래와 같이 표시됩니다.

ROI = ~ROI; // 이미지 반전
imshow( "src", src );
imshow( "ROI", ROI );

src

ROI

이상으로 Mat 클래스 초기화, 복사, 부분 추출에 대해 알아보았습니다. Mat 클래스가 OpenCV의 중요한 클래스다 보니 내용이 길어집니다.

다음 글에도 Mat 클래스에 대해 계속 알아보겠습니다.