2-3. 마스크 연산과 ROI

Region of Interest (ROI)

    직역하면 관심 영역으로 영상에서 특정 연산을 수행할 부분 영역을 뜻한다.

마스크 연산 (Masking)

    OpenCV에서 마스크 영상을 인자로 전달하여 ROI 연산 하는 함수들이 있다. (ex. cv2.copyTo, cv2.calcHist, cv2.bitwise_or, cv2.matchTemplate, etc ...)

     이때 마스크 영상은 그레이스케일 영상 (uint8 데이터 원소를 갖는 1차원 배열 형식)이며, 픽셀 값이 0이 아닌 위치에서만 연산한다.

    오늘 연구해볼 함수: cv2.copyTo(src, mask, dst=None) -> dst     <=>     dst[mask > 0] = src[mask > 0]

     저번 시간의 copy 함수와 다르게 마스크 영상으로 제공되는 ROI를 입력 영상에서 가져와 출력 영상에 복사하는 연산을 수행한다.

     여기서 src는 입력 영상, mask는 마스크 영상으로 0이 아닌 픽셀에 대해서만 복사 연산 수행, dst는 출력 영상으로 src와 크기 및 타입이 같은 영상으로 지정하면 입력이자 출력 영상이 되지만, 아니면 새로 생성하여 연산을 수행후 반환하게 된다.

     이 때 모든 인자는 같은 크기여야 하며, src와 dst는 동일한 타입의 영상이여야하며, mask는 그레이스케일 타입의 이진 영상이다.

     => bmp 파일을 사용할 경우 3차원의 RGB 컬러 영상이지만, png 파일의 경우 4차원으로 RGB에 alpha 채널이 추가되어 있으므로 차원 처리가 필요하다. (alpha 채널의 경우 1차원의 grayscale 영상으로 나타낼 수 있기 때문에 mask 영상으로도 사용 가능하다.)

     => 만약 src(&mask)와 dst가 동일한 크기가 아닐 경우, src 영상의 height와 width를 가져와 dst의 src 만큼을 잘라 픽셀(메모리)를 공유하는 변수를 만들어 copyTo 함수를 실행하면 된다.

     Numpy의 boolean indexing을 이용해 dst를 입력 영상이자 출력 영상으로 방식으로 사용할 때와 동일한 출력물을 나타낼 수 있다.

 

     아래 코드들은 예제 코드를 기반으로 영상 합성에 사용할 수 있는 두 가지 방식을 테스트 해 본 모습이다.

# import necessary package
import sys
import cv2

# 마스크 영상을 이용한 영상 합성
# copyTo를 이용할 변수 생성
src_cp2 = cv2.imread('airplane.bmp', cv2.IMREAD_COLOR)
mask_cp2 = cv2.imread('mask_plane.bmp', cv2.IMREAD_GRAYSCALE)
dst_cp2 = cv2.imread('field.bmp', cv2.IMREAD_COLOR)
# numpy boolean 이용할 변수 생성
src_bool = cv2.imread('airplane.bmp', cv2.IMREAD_COLOR)
mask_bool = cv2.imread('mask_plane.bmp', cv2.IMREAD_GRAYSCALE)
dst_bool = cv2.imread('field.bmp', cv2.IMREAD_COLOR)

# 영상 로드 잘 됬는지 확인
if src_cp2 is None or mask_cp2 is None or dst_cp2 is None:
    print('Image load failed for copyTo test!')
    sys.exit()

if src_bool is None or mask_bool is None or dst_bool is None:
    print('Image load failed for numpy boolean test!')
    sys.exit()

# 영상 합성
cv2.copyTo(src_cp2, mask_cp2, dst_cp2) 
dst_bool[mask_bool > 0] = src_bool[mask_bool > 0]

# 합성된 영상 확인
cv2.imshow('src_copyTo', src_cp2)
cv2.imshow('dst_copyTo', dst_cp2)
cv2.imshow('mask_copyTo', mask_cp2)
cv2.imshow('src_boolean', src_bool)
cv2.imshow('dst_boolean', dst_bool)
cv2.imshow('mask_boolean', mask_bool)
cv2.waitKey()
cv2.destroyAllWindows()

예제 코드를 기반으로 두 가지 ROI 연산을 확인해 본 모습. 출력 결과가 동일한 것을 확인하였다.

# import necessary package
import sys
import cv2

# 알파 채널을 마스크 영상으로 이용
src_copyto = cv2.imread('cat.bmp', cv2.IMREAD_COLOR)
src_Bool = cv2.imread('cat.bmp', cv2.IMREAD_COLOR)
logo = cv2.imread('opencv-logo-white.png', cv2.IMREAD_UNCHANGED)

# 영상 로드 잘 됬는지 확인
if src_copyto is None or src_Bool is None or logo is None:
    print('Image load failed!')
    sys.exit()

# 필요한 데이터 추출
mask_copyto = logo[:, :, 3]    # mask는 알파 채널로 만든 마스크 영상
mask_Bool   = logo[:, :, 3] 
logo_copyto = logo[:, :, :-1]  # logo는 b, g, r 3채널로 구성된 컬러 영상
logo_Bool   = logo[:, :, :-1]
h_ct, w_ct  = mask_copyto.shape[:2]        # logo, mask의 크기 추출
h_bl, w_bl  = mask_Bool.shape[:2]
crop_copyTo = src_copyto[10:10+h_ct, 10:10+w_ct]  # logo, mask와 같은 크기의 부분 영상 추출
crop_Bool = src_Bool[50:50+h_bl, 50:50+w_bl] 

# 영상 합성
cv2.copyTo(logo_copyto, mask_copyto, crop_copyTo)
crop_Bool[mask_Bool > 0] = logo_Bool[mask_Bool > 0]

# 합성된 영상 확인
cv2.imshow('src_ct', src_copyto)
cv2.imshow('logo_ct', logo_copyto)
cv2.imshow('mask_ct', mask_copyto)
cv2.imshow('src_bl', src_Bool)
cv2.imshow('logo_bl', logo_Bool)
cv2.imshow('mask_bl', mask_Bool)
cv2.waitKey()
cv2.destroyAllWindows()

예제 코드를 기반으로 png의 알파 채널을 mask 영상으로 사용하여 두 가지 영상 합성 방식을 테스트해본 위 코드의 출력물이다. boolean을 사용한 연산의 경우 crop할 화면의 위치를 달리 했기 때문에 합성된 위치가 달라진 것을 볼 수 있다.


인증 타임

포토샵으로 이미지 합성 할 때 어떤 원리로 되는 것인지 정말 궁금했었는데 직접 python 코드로 비슷한 동작을 수행하는 코드를 짜보아서 흥미로웠다. 주의할 점이 많아서 혼자 다시 코드를 작성하게 되면 헷갈릴 것 같지만 다른 영상 파일들로 테스트 해볼 가치가 충분해 보인다. 강의 영상에서 mask 이미지를 포토샵으로 구현해 오는 것이 아닌 코드로 구현하는 방식이 더 많다고 하셨는데 어떤 방식이 있을지 궁금하다.

2-3. 공부 인증 사진

 


#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #OpenCV를 활용한 컴퓨터비전과 딥러닝 올인원 패키지 Online

 

패스트캠퍼스(FastCampus) 강의 둘러보러 가기 

   

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.


 

+ Recent posts