샘플 이미지
간단 요약
로고 넣는 방법
로고 형태의 흑백사진을 얻는다.
로고 형태로 이미지에 흰색 구멍을 뚫는다.
흰색 구멍에 로고를 채워넣는다.
로고 형태의 흑백사진 얻기
필요한 변수들
//! 필요한 변수들 Mat logo_white_bg_ch3; //! 로고 3채널 이미지 (BGR) Mat logo_white_bg_ch3_rgb[3]; //! 로고 3채널 이미지의 각 채널. Mat logo_mask_black_bg_c1; //! 로고 검은색 배경 마스크 (BGR) Mat logo_mask_white_bg_c1; //! 로고 흰색 배경 마스크 (BGR) Mat logo_mask_black_bg_c3; //! 로고 검은색 배경 마스크 (Grayscale) Mat logo_mask_white_bg_c3; //! 로고 흰색 배경 마스크 (Grayscale)
STEP 1)
로고 이미지를 3채널로 불러오고, (Blue영상, Green영상, Red영상)으로 분리한다.
샘플에서 주어진 로고 이미지의 배경색은 흰색임에 주의한다.
//! 로고 이미지를 불러오고, 채널별로 분리한다.
logo_white_bg_ch3 = imread("./images/logo.png", IMREAD_COLOR);
split(logo_white_bg_ch3, logo_white_bg_ch3_rgb);
STEP 2)
위의 이미지에서 검정색인 부분을 모두 가져온다.
어떤색 and 검정색(0x000000) = 검정색 임을 이용하자.
//! 로고의 1채널 마스크를 얻는다.
logo_mask_white_bg_c1 =
logo_white_bg_ch3_rgb[0] &
logo_white_bg_ch3_rgb[1] &
logo_white_bg_ch3_rgb[2];
bitwise_not(logo_mask_white_bg_c1, logo_mask_black_bg_c1);
STEP 3)
3채널 이미지와 연산할 수 있도록,
마스크 이미지를 3채널로 변환한다.
//! 로고의 3채널 마스크로 변환. cvtColor(logo_mask_black_bg_c1, logo_mask_black_bg_c3, COLOR_GRAY2BGR); cvtColor(logo_mask_white_bg_c1, logo_mask_white_bg_c3, COLOR_GRAY2BGR);
이미지에 로고 형태로 구멍 뚫기
필요한 변수들
//! 필요한 변수들 Mat image; //! 이미지 Mat roi; //! 이미지에서 로고가 위치할 영역의 참조영역 Mat roi_clone_masked_black_logo; //! 참조영역 복사본에 검은색 로고 형태를 씌운 이미지. Mat roi_clone_masked_white_logo; //! 참조영역 복사본에 흰색 로고 형태를 씌운 이미지. Mat roi_clone_with_logo; //! 참조영역 복사본에 로고를 씌운 이미지.
STEP 1)
로고가 위치할 영역을 관심영역으로 설정한다.
//! 로고가 위치할 영역의 시작점을 구한다. Point center1 = image.size()/2; Point center2 = logo_white_bg_ch3.size() / 2; Point logo_start = center1 - center2; //! 로고가 위치할 영역을 관심영역으로 설정한다. Rect rect_roi = Rect(logo_start, logo_white_bg_ch3.size()); roi = image(rect_roi);
STEP 2)
관심영역의 복사본을 생성하면서,
로고 형태로 검정색 구멍을 뚫는다. (마스크 기법 적용)
//! 이미지에 로고 형태로 검은색 구멍을 뚫는다.
copyTo(
roi,
roi_clone_masked_black_logo,
logo_mask_white_bg_c1
);
STEP 3)
검정색 구멍을 흰색으로 변환한다.
어떤색 + 검정색(0x000000) = 어떤색 임을 이용한다.
//! 검은색 구멍을 하얀색으로 덧칠한다.
roi_clone_masked_white_logo =
roi_clone_masked_black_logo +
logo_mask_black_bg_c3;
흰색 구멍에 로고 채우기
STEP 1)
흰색 구멍에 로고를 채운다.
어떤색 and 흰색(0xFFFFFF) = 어떤색 임을 이용한다.
//! 하얀색 구멍에 로고를 씌운다.
roi_clone_with_logo =
roi_clone_masked_white_logo &
logo_white_bg_ch3;STEP 2)
완성된 로고영역을 원본 이미지에 씌운다.
//! 완성된 부분 이미지를 원본에 씌운다. roi_clone_with_logo.copyTo(roi);
전체 코드
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
//! 필요한 변수들
Mat logo_white_bg_ch3; //! 로고 3채널 이미지 (BGR)
Mat logo_white_bg_ch3_rgb[3]; //! 로고 3채널 이미지의 각 채널.
Mat logo_mask_black_bg_c1; //! 로고 검은색 배경 마스크 (BGR)
Mat logo_mask_white_bg_c1; //! 로고 흰색 배경 마스크 (BGR)
Mat logo_mask_black_bg_c3; //! 로고 검은색 배경 마스크 (Grayscale)
Mat logo_mask_white_bg_c3; //! 로고 흰색 배경 마스크 (Grayscale)
Mat image; //! 이미지
Mat roi; //! 이미지에서 로고가 위치할 영역의 참조영역
Mat roi_clone_masked_black_logo; //! 참조영역 복사본에 검은색 로고 형태를 씌운 이미지.
Mat roi_clone_masked_white_logo; //! 참조영역 복사본에 흰색 로고 형태를 씌운 이미지.
Mat roi_clone_with_logo; //! 참조영역 복사본에 로고를 씌운 이미지.
//! 이미지와 로고를 불러온다.
image = imread("./images/image.jpg", IMREAD_UNCHANGED);
logo_white_bg_ch3 = imread("./images/logo.png", IMREAD_COLOR);
imshow("logo_white_bg_ch3", logo_white_bg_ch3);
//! 로고 이미지의 1채널 마스크를 얻는다.
split(logo_white_bg_ch3, logo_white_bg_ch3_rgb);
logo_mask_white_bg_c1 =
logo_white_bg_ch3_rgb[0] &
logo_white_bg_ch3_rgb[1] &
logo_white_bg_ch3_rgb[2];
bitwise_not(logo_mask_white_bg_c1, logo_mask_black_bg_c1);
imshow("logo_mask_white_bg_c1", logo_mask_white_bg_c1);
imshow("logo_mask_black_bg_c1", logo_mask_black_bg_c1);
//! 로고 이미지의 3채널 마스크를 얻는다.
cvtColor(logo_mask_black_bg_c1, logo_mask_black_bg_c3, COLOR_GRAY2BGR);
cvtColor(logo_mask_white_bg_c1, logo_mask_white_bg_c3, COLOR_GRAY2BGR);
imshow("logo_mask_black_bg_c3", logo_mask_black_bg_c3);
imshow("logo_mask_white_bg_c3", logo_mask_white_bg_c3);
//! 이미지에서 로고가 위치할 영역의 시작지점을 구한다.
Point center1 = image.size()/2;
Point center2 = logo_white_bg_ch3.size() / 2;
Point logo_start = center1 - center2;
//! 로고가 위치할 영역을 관심영역으로 설정한다.
Rect rect_roi = Rect(logo_start, logo_white_bg_ch3.size());
roi = image(rect_roi);
imshow("roi", roi);
//! 이미지에 로고 형태로 검은색 구멍을 뚫는다.
copyTo(roi, roi_clone_masked_black_logo, logo_mask_white_bg_c1);
imshow("roi_clone_masked_black_logo", roi_clone_masked_black_logo);
//! 검은색 구멍을 하얀색으로 덧칠한다.
roi_clone_masked_white_logo = roi_clone_masked_black_logo + logo_mask_black_bg_c3;
imshow("roi_clone_masked_white_logo", roi_clone_masked_white_logo);
//! 하얀색 구멍에 로고를 씌운다.
roi_clone_with_logo = roi_clone_masked_white_logo & logo_white_bg_ch3;
imshow("roi_clone_with_logo", roi_clone_with_logo);
//! 완성된 부분 이미지를 원본에 씌운다.
roi_clone_with_logo.copyTo(roi);
imshow("image", image);
waitKey();
}
'# 미사용 > OpenCV' 카테고리의 다른 글
| [OpenCV] 이진화 (1) BINARY, BINARY_INV (0) | 2019.11.01 |
|---|---|
| [OpenCV] 행렬의 비트연산 (0) | 2019.11.01 |
| [OpenCV] 행렬의 산술연산 (0) | 2019.10.31 |
| [OpenCV] 채널의 분리, 병합, 혼합 (0) | 2019.10.31 |
| [OpenCV] 행렬의 대칭, 전치, 반복 (0) | 2019.10.30 |
images.zip