3학년/OpenCV
[OpenCV] 6장 영상의 산술 및 논리 연산
천도복숭아에이드
2023. 5. 28. 17:49
6.1 영상의 산술 연산
- 영상은 일종의 2차원 행렬이기 때문에 행렬의 산술 연산(arithmetic operation)을 그대로 적용할 수 있다
= 두개의 영상을 서로 더하거나 빼는 연산으로 새로운 결과 영상을 생성할 수 있음 - 영상의 덧셈 연산 수식: dst(x, y) = srcl(x, y) + src2(x, y)
- srcl, src2: 입력 영상
- dst: 결과 영상
- 포화 연산도 함께 수행한 덧셈 연산 수식: dst(x, y) = saturate(srcl(x, y) + src2(x, y))
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 addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);
- src1: 첫 번째 입력 행렬
- alpha: src1 행렬의 가중치
- src2: 두 번째 입력 행렬. src1과 크기와 채널 수가 같아야 한다.
- beta: src2 행렬의 가중치
- gamma: 가중합 결과에 추가적으로 더할 값
- dst: 출력 행렬. 입력 행려과 같은 크기, 같은 채널 수의 행렬이 생성됨
- 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을 반드시 지정해야 함
void absdiff(InputArray src1, InputArray src2, OutputArray dst);
- src1: 첫 번째 입력 행렬 또는 스칼라
- src2: 두 번째 입력 행렬 또는 스칼라
- dst: 출력 행렬. 입력 행렬과 같은 크기, 같은 채널 수의 행렬이 생성됨
void multiply (InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1);
- src1: 첫 번째 입력 행렬
- src2: 두 번째 입력 행렬. src1과 크기와 타입이 같아야 한다.
- dst: 출력 행렬. src1과 같은 크기, 같은 타입
- scale: 추가적으로 확대/축소할 비율
- dtype: 출력 행렬의 깊이
void divide(InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1);
- src1 : 첫 번째 입력
- src2: 두 번째 입력 행렬. src1과 크기와 타입이 같아야 한다.
- dst: 출력 행렬. src1과 같은 크기, 같은 타입
- scale: 추가적으로 확대/축소할 비율
- dtype: 출력 행렬의 깊이
- 활용 예제
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(void)
{
// 영상의 산술 연산 입력으로 상요할 영상을 그레이스케일 형식으로 불러와서
// src1과 src2 변수에 저장한다
Mat src1 = imread("lenna256.bmp", IMREAD_GRAYSCALE);
Mat src2 = imread("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;
// src1과 src2 영상을 이용하여 덧셈, 평균, 뺄셈, 차이 연산을 수행하고,
// 그 결과 영상을 각각 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;
}
6.2 영상의 논리 연산
- 영상의 논리 연산 (logical operation): 픽셀 값을 이진수로 표현하여 각 비트 단위 논리 연산을 수행하는 것을 의미
- OpenCV에서는 논리곱, 논리합, 배타적 논리합, 부정 연산을 지원
- OpenCV에서 제공하는 논리 연산 진리표
void bitwise_and (InputArray src1, InputArray src2, OuputArray dst1, InputArray mask = noArray());
void bitwise_or(InputArray src1, InputArray src2, OuputArray dst1, InputArray mask = noArray());
void bitwise_xor(InputArray src1, InputArray src2, OuputArray dst1, InputArray mask = noArray());
void bitwise_not(InputArray src1, OuputArray dst1, InputArray mask = noArray());
- src1: 첫 번째 입력 행렬 또는 스칼라
- src2: 두 번째 입력 행렬 또는 스칼라. src1과 크기와 타입이 같아야 한다.
- dst: 출력 행렬. src1과 같은 크기, 같은 타입으로 생성. dst 행렬 원소 값은 논리 연산 종류에 의해 각각 다르게 결정됨
- mask: 마스크 영상
- 예제 코드
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(void)
{
Mat src1 = imread("lenna256.bmp", IMREAD_GRAYSCALE);
Mat src2 = imread("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;
bitwise_and(src1, src2, dst1);
bitwise_or(src1, src2, dst2);
bitwise_xor(src1, src2, dst3);
bitwise_not(src1, dst4);
imshow("dst1", dst1);
imshow("dst2", dst2);
imshow("dst3", dst3);
imshow("dst4", dst4);
waitKey();
return 0;
}