이미지
이미지 비트 연산
OpenCV에서는 이미지를 대상으로 비트 연산을 수행하는 함수를 제공
비트연산 종류
cv2.bitwise(연산 이미지1, 연산 이미지2, 경과파일, 용영역)
연산 이미지1과 연산 이미지2의 값을 비트 단위로 파악하며, 두 이미지의 요소별 논리연산
논리곱(bitwise_and)
두 이미지의 요소별 논리곱을 계산논리합(bitwise_or)
논리합 함수는 두 이미지의 요소별 논리합을 계산배타적 논리합(bitwise_xor)
두 이미지의 요소별 배타적 논리합을 계산부정(bitwise_not)
연산 이미지1의 값을 비트 단위로 파악하며, 해당 비트에 대해 NOT 연산을 진행
예제
and
연산을 사용하여 penCV 로고를 오른쪽에 있는 배경사진에 합성
(로고 이미지)
(배경 이미지)
C++
[step1]
우선 로고에 대한 이진화 이미지를 만듦
[step2]
로고 이미지에서 배경을 지우고 배경 이미지에 합성하려면 2개의 이진화 이미지가 필요.
(그냥 이진화)
로고만 남기고 배경을 지우기 위해 사용하고,
Mat img_gray;
cvtColor(img_logo, img_gray, COLOR_BGR2GRAY);
Mat img_mask;
threshold(img_gray, img_mask, 200, 255, THRESH_BINARY);
(이진화 반전)
논리 부정 이용하여 반전시킴
배경에서 로고가 들어갈 부분만 배경을 지우기 위해 사용
Mat img_mask_inv;
bitwise_not(img_mask, img_mask_inv);
[step3]
로고 이미지 크기만큼 배경 이미지를 잘라내서 이미지 삽입
int height = img_logo.rows;
int width = img_logo.cols;
Mat img_roi(img_background, Rect(0, 0, width, height));
[step4]
왼쪽 이미지는 로고 이미지에서 로고만 빼고 나머지 배경을 지운 결과
오른쪽 이미지는 로고 이미지와 같은 크기를 배경 이미지 에서 가져와서 로고가 들어갈 부분만 배경을 지운 결과입니다.
Mat img1, img2;
bitwise_and(img_logo, img_logo, img1, img_mask_inv);
bitwise_and(img_roi, img_roi, img2, img_mask);
[step5]
bitwise and 연산 결과 bitwise and 연산 결과를 하나로 합치면 배경 이미지에 자연스럽게 로고가 합성됨
Mat dst;
add(img1, img2, dst);
[step6]
이제 원본 배경 이미지로 다시 복사해주면 됨
dst.copyTo(img_background(Rect(0, 0, width, height)));
최종코드
# include < opencv2/opencv.hpp>
using namespace cv;
int main()
{ // 사용할 이미지를 불러옵니다.
Mat img_logo, img_background;
img_logo = imread("logo.png", IMREAD_COLOR);
img_background = imread("background.png", IMREAD_COLOR);
// 로고를 이진화합니다.
Mat img_gray;
cvtColor(img_logo, img_gray, COLOR_BGR2GRAY);
Mat img_mask;
threshold(img_gray, img_mask, 200, 255, THRESH_BINARY);
// 배경을 지우고 로고만 배경 이미지에 보여주려면 // 반전된 이진화 이미지도 필요합니다.
Mat img_mask_inv;
bitwise_not(img_mask, img_mask_inv);
// 로고 이미지 크기만큼 배경 이미지를 잘라냅니다.
// 로고가 삽입될 위치가 됩니다.
int height = img_logo.rows;
int width = img_logo.cols;
Mat img_roi(img_background, Rect(0, 0, width, height));
// 이진화 이미지를 사용하여 로고 이미지에서는 배경을 지우고 // 배경 이미지에서는 로고가 들어갈 위치를 제거합니다.
Mat img1, img2;
bitwise_and(img_logo, img_logo, img1, img_mask_inv);
bitwise_and(img_roi, img_roi, img2, img_mask);
// bitwise_and함수를 사용한 결과를 더하면 // 배경 이미지에 로고가 합성된 결과를 얻을 수 있습니다.
Mat dst;
add(img1, img2, dst);
// 합성 결과를 배경 이미지에 복사해줍니다
dst.copyTo(img_background(Rect(0, 0, width, height)));
// 결과를 보여줍니다.
imshow("background", img_background);
// imshow("logo", img_logo);
// imshow("img_mask_inv", img_mask_inv);
// imshow("img_mask", img_mask);
// imshow("img1", img1);
// imshow("img2", img2);
// imshow("dst", dst);
waitKey(0);
}
PYTHON
[step1]
우선 로고에 대한 이진화 이미지를 만듦
[step2]
로고 이미지에서 배경을 지우고 배경 이미지에 합성하려면 2개의 이진화 이미지가 필요.
(그냥 이진화)
로고만 남기고 배경을 지우기 위해 사용하고,
img_gray = cv.cvtColor(img_logo, cv.COLOR_BGR2GRAY)
ret,img_mask = cv.threshold(img_gray, 200, 255, cv.THRESH_BINARY)
(이진화 반전)
논리 부정 이용하여 반전시킴
배경에서 로고가 들어갈 부분만 배경을 지우기 위해 사용
img_mask_inv = cv.bitwise_not(img_mask)
[step3]
로고 이미지 크기만큼 배경 이미지를 잘라
height, width = img_logo.shape[:2]
img_roi = img_background[0:height, 0:width]
[step4]
왼쪽 이미지는 로고 이미지에서 로고만 빼고 나머지 배경을 지운 결과
오른쪽 이미지는 로고 이미지와 같은 크기를 배경 이미지 에서 가져와서 로고가 들어갈 부분만 배경을 지운 결과입니다.
img1 = cv.bitwise_and(img_logo, img_logo, mask = img_mask_inv)
img2 = cv.bitwise_and(img_roi, img_roi, mask=img_mask)
[step5]
bitwise and 연산 결과 bitwise and 연산 결과를 하나로 합치면 배경 이미지에 자연스럽게 로고가 합성됨
dst = cv.add(img1, img2)
[step6]
이제 원본 배경 이미지로 다시 복사해주면 됨
img_background[0:height, 0:width] = dst
최종코드
import cv2 as cv
import numpy as np
# 사용할 이미지를 불러옵니다.
img_logo = cv.imread('logo.png', cv.IMREAD_COLOR)
img_background = cv.imread('background.png', cv.IMREAD_COLOR)
# 로고를 이진화합니다.
img_gray = cv.cvtColor(img_logo, cv.COLOR_BGR2GRAY)
ret,img_mask = cv.threshold(img_gray, 200, 255, cv.THRESH_BINARY)
# 배경 지우고 로고만 배경 이미지에 보여주려면 반전된 # 이진화 이미지도 필요합니다.
img_mask_inv = cv.bitwise_not(img_mask)
# 로고 이미지 크기만큼 배경 이미지를 잘라냅니다.
# 로고가 삽입될 위치가 됩니다.
height, width = img_logo.shape[:2]
img_roi = img_background[0:height, 0:width]
# 이진화 이미지를 사용하여 로고 이미지에서는 배경을 지우고 # 배경 이미지에서는 로고가 들어갈 위치를 제거합니다.
img1 = cv.bitwise_and(img_logo, img_logo, mask = img_mask_inv)
img2 = cv.bitwise_and(img_roi, img_roi, mask=img_mask)
# bitwise_and함수를 사용한 결과를 더하면 # 배경 이미지에 로고가 합성된 결과를 얻을 수 있습니다.
dst = cv.add(img1, img2)
# 합성 결과를 배경 이미지에 복사해줍니다.
img_background[0:height, 0:width] = dst
# 결과를 보여줍니다.
cv.imshow('background', img_background)
# cv.imshow('logo', img_logo)
# cv.imshow('img_mask_inv', img_mask_inv)
# cv.imshow('img_mask', img_mask)
# cv.imshow('img1', img1)
# cv.imshow('img2', img2)
# cv.imshow('dst', dst) cv.waitKey(0)