2025.06.29
Part13. OpenCV
- Chapter.03 OpenCV 기초 사용법 _ 1
- 03_부분 영상 다루기
- 04_마스크 연산과 ROI
- 05_투명한 PNG파일 합성하기
부분 영상 다루기
부분 영상 참조와 복사
- 부분 영상 참조 및 복사
img1 = cv2.imread('HappyFish.jpg')
img2 = omg1[40:120, 30:150] #numpy.ndarray의 슬라이싱
img3 = img1[40:120, 30:150].copy()
img2.fill(0)
img1 에서 40~120 X 30~150에 해당하는 부부인 검은색으로 변경되어 있는 건, img2.fill(0) 코드로 인해서이다. img2는 img1과 메모리를 공유(참조)하여 사용하기 때문에, img2의 변경사항이 img1에 적용된다, 이를 방지하려면, img2에 대한 깊은복사(copy())를 진행해야 한다.
부분 영상 처리
- lenna 사진데이터를 활용해서 다시 한번 해보면.. 아래와 같다.
- 메모리를 참조하기 때문에, img_face에서 변경을 하면 img도 변경된다.
아래처럼 cv2.add() 함수를 이용해서 픽셀값에 특정 숫자를 더할 수 있다. Gray Scale에서는 255에 가까울수록 흰색이므로, 밝아진다.
아래처럼 cv2.circle( ) 함수를 이용해 원을 그려 넣을 수도 있다. 이 경우 픽셀값을 0으로 하면 검은색, 255로 하면 흰색이다.
마스크 연산과 ROI
관심 영역 (ROI) 개요
- 관심 영역 (ROI)
- Region of Interest = ROI
- 영상에서 특정 연산을 수행하고자 하는 임의의 부분 영역
- 마스크 연산
- OpenCV는 일부 함수에 대해 ROI연산을 지원하며, 이 때 마스크 영상 (mask image)을 인자로 함께 전달해야 한다.
- (e.g.) cv2.copyTo( ), cv2.calcHist( ), cv2.bitwise_or( ), cv2.matchTemplate( ), etc.
- 마스크 영상은 cv2.CV_8UC1 타입 (GrayScale 영상)
- 마스크 영상의 픽셀값이 0이 아닌 위치에서만 연산이 수행됨.
- 보통 마스크 영상으로는 0 또는 255로 구성된 이진 영상(binary image)을 사용
- 관심이 없는 부분은 0으로 처리, 처리할 부분은 255 (흰색)으로 표현
- OpenCV는 일부 함수에 대해 ROI연산을 지원하며, 이 때 마스크 영상 (mask image)을 인자로 함께 전달해야 한다.
cv2.copyTo( ) 함수와 마스크 연산
- 마스크 연산을 지원하는 픽셀 값 복사 함수
cv2.copyTo(src, mask, dst=None) → dst
- src : 입력 영상
- mask : 마스크 영상. cv2.CV_8U.(numpy.uint8), 0이 아닌 픽셀에 대해서만 복사연산 수행.
- dst : 출력 영상, 만약 src와 크기 및 타입이 같은 dst를 입력으로 지정하면 dst를 새로 생성하지 않고 연산을 수행. 그렇지 않으면 dst를 새로 생성하여 연산 수행한 후 반환함
import cv2
import sys
# 마스크 영상을 이용한 영상 합성
scr = cv2.imread('airplane.bmp', cv2.IMREAD_COLOR)
mask = cv2.imread('mask_plane.bmp', cv2.IMREAD_GRAYSCALE) # mask영상은 grayscale
dst = cv2.imread('field.bmp', cv2.IMREAD_COLOR)
if scr is None or mask is None or dst is None:
print('Image load failed')
sys.exit()
cv2.imshow('scr', scr)
cv2.imshow('mask', mask)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.copyTo(scr, mask, dst)
cv2.imshow('scr', scr)
cv2.imshow('mask', mask)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
1) 처음 imshow( ) 통해서 각 영상데이터 확인
2) copyTo( ) 함수를 통해서, scr 영상데이터에서 mask 영상에서 255인 픽셀값에 해당하는 곳 픽셀값 복사하여 dst 로 복사.
비행기가 있는 부분에 대해서만 픽셀값을 복사해서 dst 영상데이터에 넣는다.
cv2.copyTo(scr, mask, dst) 코드는 아래와 같이 사용할 수 있다.
dst[ mask > 0 ] = scr[ mask > 0 ]
투명한 PNG파일 합성하기
4채널 PNG파일 분석
- 알파 채널이 있는 PNG파일( 4채널, (b,g,r,a) )을 다른 영상에 합성하기
하려고 하는건, 위에서 배운 mask 영상(copyTo)을 활용해서, OpenCV 로고 영상을 Cat 영상 좌측상단에 합성하는 것이다. 이때 PNG 알파채널을 이용해서 (b,g,r)채널에 있는 값은 합성하고, 나머지 값은 투명하게 처리하여 합성하는 과정을 알아본다.
- 투명한 PNG 파일합성 예제)
scr = cv2.imread('cat.bmp', cv2.IMREAD_COLOR)
logo = cv2.imread('opencv-logo-white.png', cv2.IMREAD_UNCHANGED)
# cv2.IMREAD_UNCHANGED 지정해야 4채널 불러와짐
cv2.imshow('cat_img', scr)
cv2.imshow('logo_img', logo)
cv2.waitKey()
cv2.destroyAllWindows()
mask = logo[:,:,3] # PNG파일 (b, g, r, a)에서 a, 즉 알파채널
logo = logo[:,:,0:3] # logo는 b,g,r 3채널로 구서오딘 컬러영상
h, w = mask.shape[:2]
crop = scr[10:10+h, 10:10+w]
cv2.copyTo(logo, mask, crop)
# logo, mask, crop 모드 크기가 같아야 한다.
# logo와 crop은 같은 타입이어야 하고, mask는 grayscale 타입이어야 한다.
# 얕은복사 활용
cv2.imshow('cat_img', scr)
cv2.waitKey()
cv2.destroyAllWindows()
crop = scr[10:10+h, 10:10+w]는 단순히 데이터를 복사하는 게 아니라 얕은 복사(shallow copy), 즉 scr의 특정 영역에 대한 뷰(view)를 만드는 것. 그래서 이 crop을 수정하면 원본인 scr도 함께 변경됨.
cv2.copyTo(logo, mask, crop)에서 crop이 대상(target) 역할을 하고 있어서, logo 이미지가 mask에 따라 crop 영역에 복사되면 이는 곧 scr의 해당 영역이 바뀌는 거고 —> 그래서 최종적으로 다시 scr을 imshow() 하면 logo가 들어간 이미지가 나타나는 거지!
'Bootcamp_zerobase > OpenCV' 카테고리의 다른 글
OpenCV 기초 사용법 2 : 카메라와 동영상 처리 (1) | 2025.07.13 |
---|---|
영상데이터 다루기 (OpenCV 기초 사용법) (1) | 2025.06.29 |
OpenCV 주요 함수 사용법 (0) | 2025.06.03 |
OpenCV 개요 (2) | 2025.06.01 |
영상 데이터의 구조와 종류 (0) | 2025.05.31 |