[OpenCV 4] 6. 영상의 산술 및 논리 연산
영상의 산술 연산
영상은 일종의 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()); |
다음과 같은 논리 연산 함수가 있다. 처음 봐서 간단히 설명만 하겠다. 실제로 영상처리를 하면서 위와 같은 함수는 사용해본 기억이 없긴 하다.
참고자료 : OpenCV 4로 배우는 컴퓨터 비전과 머신러닝