크로마 키 (Chroma Key)
크로마키(Chroma Key)는 영상 속에서 픽셀 단위로 특정 색상을 제거하고 그 배경을 다른 이미지나 영상으로 대체하는 기술이다. 크로마키는 어떤 색상이든 선택할 수 있지만 일반적으로 초록색이 가장 분리하기 쉽기 때문에 흔히 사용된다.
Python + OpenCV
아래코드는 초록색 배경을 제거하고 다른 이미지로 대체하는 간단한 크로마키 예제이다.
# 윈도우
pip install opencv-python
# 리눅스
sudo apt update
sudo apt install python3-pip
pip3 install opencv-python
import cv2
import numpy as np
def chroma_key_example():
# 이미지 불러오기
src = cv2.imread('chromakey_src.jpg') # 녹색 배경을 가진 원본 이미지
bg = cv2.imread('background.png') # 합성할 새 배경 이미지
if src is None or bg is None:
print("cannot load images.")
return
# 배경 이미지 크기를 src와 동일하게 조정
bg = cv2.resize(bg, (src.shape[1], src.shape[0]))
# BGR을 HSV로 변환
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
# 마스크 생성 (녹색 배경 추출)
lower_green = np.array([35, 40, 40])
upper_green = np.array([85, 255, 255])
mask = cv2.inRange(hsv, lower_green, upper_green)
# 반전 마스크 (피사체 부분)
mask_inv = cv2.bitwise_not(mask)
# 배경에서 피사체 영역 제거
bg_part = cv2.bitwise_and(bg, bg, mask=mask)
# 원본에서 배경 제거
fg_part = cv2.bitwise_and(src, src, mask=mask_inv)
# 최종 합성
final = cv2.add(fg_part, bg_part)
# 출력
cv2.imshow('Original', src)
cv2.imshow('Mask (Background)', mask)
cv2.imshow('Foreground (Subject)', fg_part)
cv2.imshow('Background (Masked)', bg_part)
cv2.imshow('Chroma Key Result', final)
cv2.waitKey(0)
cv2.destroyAllWindows()
chroma_key_example()
OpenCV(Python) 이미지 배열의 구성
OpenCV(cv2)로 이미지를 불러오면 그 이미지는 NumPy 배열이고, 이미지의 픽셀 데이터는 BGR(Blue, Green, Red) 형식으로 불러온다.
img = cv2.imread("your_image.jpg")
print(img.shape) # [height, width, channels], shape은 배열의 차원별 크기를 나타내는 멤버변수이다.
print(img[0, 0]) # [Blue, Green, Red]
HSV 색공간으로 먼저 변환하는 이유는?
영상은 일반적으로 RGB(또는 BGR) 색공간으로 표현되지만, RGB는 밝기와 색상이 분리되어 있지 않아 색상 기반 탐지에 불리하다. 반면 HSV(Hue, Saturation, Value) 색공간은 색조(Hue) 정보를 분리해주기 때문에 특정 색상을 정밀하게 분리할 수 있다.
HSV란?

HSV는 다음 세 가지 요소로 색을 표현하는 색공간(Color Space)이다. 일반적으로 RGB 데이터를 기반으로 소프트웨어적으로 변환한 결과로, 주로 이미지 처리나 분석 단계에서 사용된다.
- H (Hue) : 색상 (빨강, 초록, 파랑 등)
- 범위 : 일반적으로 0~360인데, OpenCV에서는 한 바이트 내로 표현하기 위해 절반인 0~179로 줄여서 쓴다.
- S (Saturation) : 채도 (색의 강도)
- 범위 : 0~255
- V (Value) : 명도 (밝기)
- 범위 : 0~255
Hue 값에 따른 색상 스펙트럼은 다음과 같으며, OpenCV에선 /2해서 생각해야 한다.

HSV 색공간에서 초록색 범위 지정
아래 코드는 HSV 색공간에서 초록색으로 간주할 범위를 지정하는 것이다.
lower_green = np.array([35, 40, 40])
upper_green = np.array([85, 255, 255])
- Hue 35~85 : 초록색 계열에 해당하는 색상 범위이다.
- Saturation 40~255 : 너무 채도가 낮은 것은 제외하고, 색감이 있는 것만 남긴다.
- Value 40~255 : 너무 어두운 픽셀은 제거해서 정확도를 높인다.
cv2.inRange
이 함수는 OpenCV에서 특정 색상 범위에 해당하는 픽셀을 마스크(mask) 형태로 추출할 때 사용하는 함수이다.
위 예제에서는 HSV 색공간으로 변환된 이미지에서 lower_green과 upper_green 사이에 있는 픽셀은 255(흰색), 그 외는 0(검정)으로 표시하는 mask 이미지를 만든다.
cv2.inRange(src, lowerb, upperb) → dst
- 파라미터
- src : 입력 영상
- lowerb : 범위의 하한값, ex. np.array([35, 40, 40])
- upperb 범위의 상한값, ex. np.array([85, 255, 255])
- 리턴값 : 입력 영상과 같은 크기의 이진 마스크 이미지
Mask 연산과 Chroma Key의 차이
- 마스크 연산 : 별도로 존재하는 마스크 영상을 이용해 연산 적용 여부를 제어한다. 마스크 영상은 보통 흑백이고 이진 형태(0, 255)가 대부분이며, 필터링, 색상 변경, 복사 등 조건부 처리에 다양하게 활용된다.
- 크로마키 : 마스크가 존재하지 않는 상태에서, 특정 색상이 있는 영역을 마치 마스크로 간주하여 처리하는 방식이다. 특정 색상 범위 내의 픽셀을 탐지하여 마스크를 만들고, 해당 영역의 알파값을 0(투명)으로 처리해 다른 배경과 합성하는 것이 주 목적이다.
2022.08.18 - [프로그래밍/OpenCV] - OpenCV, C++ ] setTo(), copyTo() 함수와 마스크 연산
'프로그래밍 > OpenCV' 카테고리의 다른 글
| OpenCV, C++ ] 영상의 밝기 조절 + 명암비 조절 + 히스토그램 분석 (0) | 2022.08.23 |
|---|---|
| OpenCV, C++ ] 유용한 함수들. sum(), mean(), minMaxLoc(), normalize(), cvRound() (0) | 2022.08.18 |
| OpenCV, C++ ] 연산 시간 측정, TickMeter 클래스 또는 getTickCount() 와 getTickFrequency() 함수 사용 (0) | 2022.08.18 |
| OpenCV, C++ ] setTo(), copyTo() 함수와 마스크 연산 (0) | 2022.08.18 |
| OpenCV, C++ ] 데이터 파일 입출력 (0) | 2022.08.18 |