샘플 이미지
간단 요약
로고 넣는 방법
로고 형태의 흑백사진을 얻는다.
로고 형태로 이미지에 흰색 구멍을 뚫는다.
흰색 구멍에 로고를 채워넣는다.
로고 형태의 흑백사진 얻기
필요한 변수들
//! 필요한 변수들 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 |