OpenCV 비전 실무4장 · 채널 처리와 히스토그램 분석15 / 21← 이전목차다음 →MetaContents

4장. 채널 처리와 히스토그램 분석

실습 2 — 채널 하나만 색으로 보기와 바꿔치기

채널 하나를 그 색으로 보이게 만들어 2×2 격자로 띄우고, cv2.merge 의 순서를 바꿔 색을 바꿔치기합니다. 바꿔치기한 그림은 out_ch04_swapped.png 로 저장합니다.

1단계. 채널마다 그 색으로 보이는 그림 만들기

Python
import cv2
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams["font.family"] = "Malgun Gothic"
plt.rcParams["axes.unicode_minus"] = False

img = cv2.imread("ch04_scenes/sunset.png")
b, g, r = cv2.split(img)
# np.zeros_like: r 과 모양·자료형이 같은 0 배열. 빈 채널 자리를 채운다
zero = np.zeros_like(r)

# 자기 자리에만 채널을 넣고 나머지 두 자리는 0 으로 채운다
blue_only = cv2.merge([b, zero, zero])
green_only = cv2.merge([zero, g, zero])
red_only = cv2.merge([zero, zero, r])

# 해 한가운데 칸이 세 그림에서 어떻게 남았는지 본다
for name, arr in [("파랑만", blue_only), ("초록만", green_only), ("빨강만", red_only)]:
    print(f"{name}: {[int(v) for v in arr[140, 200]]}")
출력
파랑만: [120, 0, 0]
초록만: [0, 220, 0]
빨강만: [0, 0, 255]

2단계. 2×2 격자로 띄우기

Python
fig, axes = plt.subplots(2, 2, figsize=(8, 6))
panels = [("원본", img), ("B 채널만 (파랑으로)", blue_only),
          ("G 채널만 (초록으로)", green_only), ("R 채널만 (빨강으로)", red_only)]
# axes.flat: 2×2 칸을 한 줄로 펴서 차례로 꺼낸다
for ax, (title, arr) in zip(axes.flat, panels):
    ax.imshow(cv2.cvtColor(arr, cv2.COLOR_BGR2RGB))   # 컬러는 RGB 로 바꿔 띄운다
    ax.set_title(title)
    ax.axis("off")
plt.tight_layout()
plt.show()
노을 그림의 원본과 B, G, R 채널을 각각 파랑, 초록, 빨강으로 띄운 2행 2열 결과

3단계. 채널 순서 바꿔치기

Python
# 빨강과 파랑 자리를 맞바꾼다: [r, g, b] 순서로 합친다
swap_rb = cv2.merge([r, g, b])
# 초록과 빨강 자리를 맞바꾼다: [b, r, g] 순서로 합친다
swap_gr = cv2.merge([b, r, g])

print("원본 해 칸     :", [int(v) for v in img[140, 200]])
print("R↔B 바꾼 해 칸 :", [int(v) for v in swap_rb[140, 200]])
print("G↔R 바꾼 해 칸 :", [int(v) for v in swap_gr[140, 200]])

# 바꿔치기한 그림의 채널 평균도 자리가 바뀐다
print("원본 평균(B, G, R)    :", [round(v, 1) for v in cv2.mean(img)[:3]])
print("R↔B 바꾼 평균(B, G, R):", [round(v, 1) for v in cv2.mean(swap_rb)[:3]])
출력
원본 해 칸     : [120, 220, 255]
R↔B 바꾼 해 칸 : [255, 220, 120]
G↔R 바꾼 해 칸 : [120, 255, 220]
원본 평균(B, G, R)    : [61.1, 86.6, 185.5]
R↔B 바꾼 평균(B, G, R): [185.5, 86.6, 61.1]

4단계. 견주어 보고 저장하기

Python
fig, axes = plt.subplots(1, 3, figsize=(11, 3.2))
for ax, (title, arr) in zip(axes, [("원본", img), ("R↔B 바꿈", swap_rb), ("G↔R 바꿈", swap_gr)]):
    ax.imshow(cv2.cvtColor(arr, cv2.COLOR_BGR2RGB))
    ax.set_title(title)
    ax.axis("off")
plt.tight_layout()
plt.show()

# 빨강과 파랑을 바꾼 그림을 저장한다
print("저장:", cv2.imwrite("out_ch04_swapped.png", swap_rb))
출력
저장: True
원본 노을, 빨강과 파랑을 바꾼 그림, 초록과 빨강을 바꾼 그림을 나란히 놓은 결과

코드 설명

  • np.zeros_like(r) 은 r 과 모양과 자료형이 같은 0 배열입니다. 빈 채널 자리를 채워 cv2.merge 에 넣을 세 장을 맞춥니다.
  • cv2.merge([zero, zero, r]) 는 B, G 자리가 0 이라 빨강으로만 보입니다. 해 칸은 [0, 0, 255] 가 됩니다.
  • cv2.merge([r, g, b]) 는 빨강 숫자를 파랑 자리에 넣습니다. 해 칸 [120, 220, 255] 가 [255, 220, 120] 이 되어 노란 해가 하늘색으로, 붉은 하늘이 파란 하늘로 바뀝니다. 초록과 빨강을 바꾸면 하늘이 연두색이 됩니다.
  • 바꿔치기는 숫자를 새로 만들지 않고 자리만 옮깁니다. 그래서 채널 평균 세 개도 값은 그대로이고 자리만 바뀝니다.
← 이전 절4장 · 실습 1 — 채널 나누고 합치기다음 절 →4장 · 실습 3 — 채널 평균으로 사진의 색 경향 분석하기