4장. 채널 처리와 히스토그램 분석
실습 2 — 채널 하나만 색으로 보기와 바꿔치기
채널 하나를 그 색으로 보이게 만들어 2×2 격자로 띄우고, cv2.merge 의 순서를 바꿔 색을 바꿔치기합니다. 바꿔치기한 그림은 out_ch04_swapped.png 로 저장합니다.
1단계. 채널마다 그 색으로 보이는 그림 만들기
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 격자로 띄우기
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()
3단계. 채널 순서 바꿔치기
# 빨강과 파랑 자리를 맞바꾼다: [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단계. 견주어 보고 저장하기
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]이 되어 노란 해가 하늘색으로, 붉은 하늘이 파란 하늘로 바뀝니다. 초록과 빨강을 바꾸면 하늘이 연두색이 됩니다.- 바꿔치기는 숫자를 새로 만들지 않고 자리만 옮깁니다. 그래서 채널 평균 세 개도 값은 그대로이고 자리만 바뀝니다.