[OpenCV] 마스크 연산 – setTo, copyTo

이번 글에서는 setTo와 copyTo 함수에 대해 알아보겠습니다.

setTo

우선 setTo부터 알아보겠습니다.

/**
@param value 원소에 설정할 값
@param mask 마스크 행렬. 행렬 원소 값이 0이 아닌 위치에 value가 설정 됨
*/
Mat& setTo(InputArray value, InputArray mask=noArray());

setTo 함수를 사용하기 위해서는 원본 영상과 마스크 영상의 크기가 같아야 합니다. 또한 보통 마스크 영상은 0 또는 255로 구성된 흑백 영상이 사용됩니다.

아래와 같이 가운데가 흰색으로 뚫려있는 이미지가 있을 때, setTo함수를 사용하면 흰색 부분에 노란색으로 설정합니다.

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

#ifdef _DEBUG
#pragma comment(lib, "opencv_world440d.lib")
#else
#pragma comment(lib, "opencv_world440.lib")
#endif

using namespace std;
using namespace cv;

void setTo_mask();

int main(void)
{
	setTo_mask();

	system("pause");
	return 0;
}

void setTo_mask()
{
	Mat src, mask;
	src = imread("lenna.bmp");
	mask = imread("mask.bmp");
	if (src.empty() || mask.empty())
	{
		cerr << "image load fail" << endl;
		return;
	}

	src.setTo(Scalar(0, 255, 255), mask); // 흰색 부분을 노란색으로 변경

	imshow("src", src);
	imshow("mask", mask);

	waitKey();
	destroyAllWindows();
}

실행 결과는 아래와 같습니다.

copyTo

그 다음으로 copyTo에 대해 알아보겠습니다.

/**
@param m 저장될 행력. 크기 & 타입이 다르면 새로 생성됨
@param mask 마스크 행렬
*/
void copyTo( OutputArray m, InputArray mask ) const;

setTo가 마스크 영상에서 ROI를 설정하여 값을 변경 했다면, copyTo는 ROI를 설정하여 복사합니다.

샘플 코드는 아래와 같습니다.

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

#ifdef _DEBUG
#pragma comment(lib, "opencv_world440d.lib")
#else
#pragma comment(lib, "opencv_world440.lib")
#endif

using namespace std;
using namespace cv;

void setTo_mask();
void copyTo_mask();

int main(void)
{
	setTo_mask();
	copyTo_mask();

	system("pause");
	return 0;
}

void setTo_mask()
{
	Mat src, mask;
	src = imread("lenna.bmp");
	mask = imread("mask.bmp");
	if (src.empty() || mask.empty())
	{
		cerr << "image load fail" << endl;
		return;
	}

	src.setTo(Scalar(0, 255, 255), mask); // 흰색 부분을 노란색으로 변경

	imshow("src", src);
	imshow("mask", mask);

	waitKey();
	destroyAllWindows();
}

void copyTo_mask()
{
	Mat src, mask, dst;
	src = imread("lenna.bmp");
	mask = imread("mask.bmp");
	dst = imread("dst.bmp");

	if (src.empty() || mask.empty() || dst.empty())
	{
		cerr << "image load fail" << endl;
		return;
	}

	src.copyTo(dst, mask);

	imshow("src", src);
	imshow("mask", mask);
	imshow("dst", dst);

	waitKey();
	destroyAllWindows();
}

실행 결과는 아래와 같습니다.