Computer Vision/OpenCV

[OpenCV 4] 6. 영상의 산술 및 논리 연산

SooHyun2i 2020. 11. 13. 01:43

영상의 산술 연산

 

영상은 일종의 2차원 행렬이기 때문에 행렬의 산술 연산(arithmetic operation)을 그대로 적용할 수 있다. 즉, 두 개의 영상을 서로 더하거나 빼는 연산을 수행함으로써 새로운 결과 영상을 생성할 수 있다. 다만 영상을 서로 곱하거나 나누는 연산은 거의 사용하지 않는다.

 

덧셈, 뺄셈 연산은 그냥 말그대로 덧셈과 뺄셈 그 자체이다.

 

void add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1);

 src1

첫 번째 입력 행렬 또는 스칼라

 src2

두 번째 입력 행렬 또는 스칼라

 dst

입력 행렬과 같은 크기, 같은 채널 수를 갖는 출력 행렬. dst의 깊이는 src1, src2의 깊이와 같거나 또는 dtype 인자에 의해 결정됩니다.

 mask

8비트 1채널 마스크 영상. mask 행렬 원소 값이 0이 아닌 위치에서만 덧셈 연산을 수행합니다.

 dtype

출력 행렬의 깊이. src1 src2의 깊이가 같은 경우에는 dtype에 -1을 지정할 수 있고, 이 경우 dst의 깊이는 src1, src2와 같은 깊이로 설정됩니다. src1 src2의 깊이가 서로 다른 경우에는 dtype을 반드시 지정해야 합니다.

void subtract(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1);

 src1

첫 번째 입력 행렬 또는 스칼라

 src2

두 번째 입력 행렬 또는 스칼라

 dst

입력 행렬과 같은 크기, 같은 채널 수를 갖는 출력 행렬. dst의 깊이는 src1, src2의 깊이와 같거나 또는 dtype 인자에 의해 결정됩니다.

 mask

8비트 1채널 마스크 영상. mask 행렬 원소 값이 0이 아닌 위치에서만 덧셈 연산을 수행합니다.

 dtype

출력 행렬의 깊이. src1과 src2의 깊이가 같은 경우에는 dtype에 -1을 지정할 수 있고, 이 경우 dst의 깊이는 src1, src2와 같은 깊이로 설정됩니다. src1과 src2의 깊이가 서로 다른 경우에는 dtype을 반드시 지정해야 합니다.

간단한 함수 설명이다. 너무 쉽기 때문에 코드 예제로만 언급하고 넘어가겠다.

 

int main(void)
{
	Mat src1 = imread("image/lenna256.bmp", IMREAD_GRAYSCALE);
	Mat src2 = imread("image/square.bmp", IMREAD_GRAYSCALE);

	if (src1.empty() || src2.empty()) {
		cerr << "Image load failed!" << endl;
		return -1;
	}

	imshow("src1", src1);
	imshow("src2", src2);

	Mat dst1, dst2, dst3, dst4;

	add(src1, src2, dst1);
	addWeighted(src1, 0.5, src2, 0.5, 0, dst2);
	subtract(src1, src2, dst3);
	absdiff(src1, src2, dst4);

	imshow("dst1", dst1);
	imshow("dst2", dst2);
	imshow("dst3", dst3);
	imshow("dst4", dst4);
	waitKey();

	return 0;
}

위와 같이 코드를 작성하면

 

dst1 : add 연산

dst2 : addweight (0.5로 줌)

dst3 : sub 연산

dst4 : 차영상 , 사각형 안쪽 영역에서만 반전이 되는 효과가 나타나게 된다. 

 

absdiff() 함수 : 차영상 구하는 함수

 

위 함수를 처음 봐서 눈에 확 알아 볼 수 있는 예를 들어보겠다.

위와 같이 움직이는 자동차 영역에서만 픽셀 값 차이가 두드러지게 나타나고 변화가 없는 부분은 픽셀 값이 0에 가까운 검은색으로 채워진다. 

 


영상의 논리 연산

 

영상의 논리 연산(logical operation)은 픽셀 값을 이진수로 표현하여 각 비트(bit) 단위 논리 연산을 수행하는 것을 의미한다. OpenCV에서는 다양한 논리 연산 중에서 논리곱(AND), 논리합(OR), 배타적 논리합(XOR), 부정(NOT) 연산을 지원한다. 

논리 연산 진리표이다. 

영상의 논리 연산은 각 픽셀 값에 대하여 비트 단위로 이루어진다. 그레이스케일 영상의 경우, 한 픽셀을 구성하는 여덟 개의 비트에 모두 논리 연산이 이루어진다. 

 

예를 들어 영상의 특정 좌표에 있는 픽셀의 그레이스케일 값이 각각 110과 200인 경우 논리 연산을 하면 다음과 같다.

void bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray()); 
void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray()); 
void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray()); 
void bitwise_not(InputArray src1, OutputArray dst, InputArray mask = noArray());

다음과 같은 논리 연산 함수가 있다. 처음 봐서 간단히 설명만 하겠다. 실제로 영상처리를 하면서 위와 같은 함수는 사용해본 기억이 없긴 하다.

 

참고자료 : OpenCV 4로 배우는 컴퓨터 비전과 머신러닝