logo

크로마 키 합성

특정 색상만 추출

image = cv.imread('balloon.webp')
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
  • HSV에서 H가 4080 사이, SV는 50255 사이인 부분만 추출
lower = np.array([40, 50, 50])
upper = np.array([80, 255, 255])
mask = cv.inRange(hsv, lower, upper)
Image.fromarray(mask)
  • 원래 이미지에서 mask 부분만 보기
cv.bitwise_and(image, image, mask=mask)

특정 색상만 추출 이미지 1

특정 색상만 추출 이미지 2

특정 색상만 추출 다이어그램 1

크로마 키를 이용한 합성

foreground = cv.imread('chroma-key.jpg')
background = cv.imread('desert.jpg')

# 배경 크기 리사이즈
height, width = foreground.shape[:2]
background = cv.resize(background, (width, height))

# 인물 이미지를 HSV로 변환
hsv = cv.cvtColor(foreground, cv.COLOR_BGR2HSV)

크로마 키를 이용한 합성 (1) 이미지 1

크로마 키를 이용한 합성 (1) 이미지 2

# 크로마 키 색 범위
lower_green = np.array([40, 100, 100])
upper_green = np.array([60, 255, 255])

# 마스크 만들기
mask = cv.inRange(hsv, lower_green, upper_green)
mask_inv = cv.bitwise_not(mask)

크로마 키를 이용한 합성 (2) 이미지 1

크로마 키를 이용한 합성 (2) 이미지 2

# 전경에서 인물만 뽑기
fg_isolated = cv.bitwise_and(foreground, foreground, mask=mask_inv)

# 배경에서 인물만큼 잘라내기
bg_isolated = cv.bitwise_and(background, background, mask=mask)

# 합치기
final_output = cv.add(fg_isolated, bg_isolated)

크로마 키를 이용한 합성 (3) 이미지 1

비트와이즈 연산

  • 각각의 비트를 비교하여 비트 단위로 AND 연산
a = 10
bin(a) # 이진수 1010
aa = np.array(a) # 배열로 바꿈

b = 12
bin(b) # 이진수 1100
bb = np.array(b)

cc = cv.bitwise_and(aa, bb)
c = cc.item() # cc == 8
bin(c)  # 이진수 1000

비트와이즈 AND 다이어그램 1

  • 각각의 비트를 비교하여 비트 단위로 OR 연산
dd = cv.bitwise_or(aa, bb)
d = dd.item() # dd == 14
bin(d)  # 이진수 1110
  • 각각의 비트를 비교하여 비트 단위로 XOR 연산
ee = cv.bitwise_xor(aa, bb)
e = ee.item() # dd == 6
bin(e)  # 이진수 0110

비트와이즈 OR과 XOR 다이어그램 1

마스크

  • 마스크를 적용할 경우, 마스크에 색이 존재하는(1보다 큰) 영역에서만 비트와이즈 연산을 적용
src = np.array([[10, 12]])
mask = np.array([[1, 0]], dtype=np.uint8)

# mask가 없으면 10과 10, 12와 12의 비트와이즈 AND 연산
cv.bitwise_and(src, src)

# mask가 있으면, mask 값이 0보다 큰 10과 10만 비트와이즈 AND 연산
cv.bitwise_and(src, src, mask=mask)
Previous
이미지 변형