Color Processing

파워·2024년 12월 4일

의학영상처리

목록 보기
10/10
post-thumbnail

Color Models


RGB Color Model

RGB 모델은 디지털 화면에서 주로 사용됩니다. 각 픽셀은 빨강(R), 초록(G), 파랑(B)의 조합으로 나타내며, (0, 0, 0)은 검정, (255, 255, 255)는 흰색을 나타냅니다. 중간값(예: (127, 127, 127))은 회색 음영을 표현합니다. RGB 값을 조합해 다양한 색상을 생성하며, 이는 색상 큐브(Color Cube)로 시각화할 수 있습니다.



HSV Color Model

Hue(색조)

색의 "본질적인 색깔"을 나타내며, 0 ~ 360도로 표현됩니다(예: 빨강, 초록, 파랑 등).


Saturation(채도)

색의 순도를 나타내며, 0% ~ 100% 범위로 표현됩니다. 100% 는 순수 색깔, 0% 는 회색(무채색)입니다.


Value(명도)

색의 밝기를 나타내며 0% ~ 100% 범위로 표현됩니다. 0% 는 검정색, 100% 는 최대 밝기입니다.

HSV 는 인간의 색 지각과 더 가까운 방식으로 색을 표현합니다.


RGB -> HSV 변환

변환 과정:

  1. VVSS 계산
  • V=max(R,G,B)V = \text{max}(R, G, B) : 세 색 중 가장 큰 값

  • S=Vmin(R,G,B)VS = \frac{V - \text{min}(R, G, B)}{V} : 밝기 대비 색 순도를 계산


  1. HH 계산
  • HH 는 어떤 색이 가장 간한지에 따라 계산 방식이 달라집니다.

    • RR 이 강하면: H=16×(GB)δH = \frac{1}{6} \times \frac{(G-B)}{\delta}
    • GG 이 강하면: H=16×(2+BRδ)H = \frac{1}{6} \times (2 + \frac{B - R}{\delta})
    • BB 이 강하면: H=16×(4+RGδ)H = \frac{1}{6} \times (4+\frac{R-G}{\delta})
  • δ\delta : Vmin(R,G,B)V - \text{min}(R, G, B)

  • 예: RGB 값 [0.2, 0.4, 0.6] -> HSV 값 [0.583, 0.667, 0.6]


HSV -> RGB 변환

변환 과정:

  1. HH\prime 계산
  • H=6HH{\prime} = \lfloor 6H \rfloor : HH 를 6으로 곱한 후 소수점을 제거합니다.
  1. RGB 계산
  • HH\prime 에 따라 P,Q,TP, Q, T 를 계산하고, 아래의 표를 참고하여 순서대로 RGB 를 조합합니다.
    • P=V(1S)P = V(1-S)
    • Q=V(1SF)Q = V(1 - SF)
    • T=V(1S(1F))T = V(1 - S(1 - F))



YIQ/YUV Color Model

YIQ

  • NTSC(Standard for U.S.)에 의해 정의된 컬러 스페이스로, 미국, 한국 등 NTSC 표준을 사용하는 국가에서 TV 및 비디오 용도로 사용됩니다.

  • YY : 밝기(Luminance)를 나타내며, 명도 정보를 포함합니다.

  • I,QI, Q : 색상 정보를 나타냅니다.

  • 인간의 눈은 IIQQ 보다 YY 에 더 민감합니다.


YUV

  • PAL 표준(유럽 아날로그 TV)을 기반으로 합니다.

  • YIQ 와 개념은 유사하지만, 사용 지역과 기술적 세부 차이가 있습니다.

  • YIQ 와 개념은 유사하지만, 사용 지역과 기술적 세부 차이가 있습니다.


수학적 변환

Python 에서 RGB 와 YIQ 의 변환을 구현할 수 있습니다.

import skimage.color as co
co.rgb2yiq(rgb_image)
co.yiq2rgb(yiq_image)



Python 에서의 Color Image

RGB 채널 분리

x = io.imread('twins.png')
print(x.shape)  # (256, 256, 3)

io.imshow(x)
for i in range(3):
	plt.figure(i+2)
    io.imshow(x[:,:,i])

RGB to HSV 변환

xh = sk.color.rgb2hsv(x)
for i in range(3):
	plt.figure(i)
    io.imshow(xh[:,:,i])

RGB to YIQ 변환

rgb2yiq = np.array([[0.299, 0.587, 0.114],
                    [0.596, -0.275, -0.321],
                    [0.211, -0.523, 0.312]])
xyiq = x.dot(rgb2yiq)

for i in range(3):
	plt.figure(i)
    io.imshow(xyiq[:,:,i])




Pseudo-coloring


Pseudo-coloring 은 흑백(그레이스케일) 이미지를 다양한 색상을 사용하여 시각적으로 더 유용하게 변환하는 기법입니다. 이 과정에서 픽셀의 밝기 값을 특정 색상 범위에 매핑하여 데이터를 더 쉽게 이해할 수 있도록 돕습니다.

Intensity Slicing

이미지를 여러 그레이 레벨 범위로 나눕니다. 각 범위에 특정 색상을 할당합니다. 예를 들어:

  • 0 ~ 63 그레이 레벨은 파란색

  • 64 ~ 127 은 마젠타

  • 128 ~ 191 은 초록색

  • 192 ~ 255 는 빨간색

으로 할당합니다. 아래 차트에서는 그레이 레벨과 색상을 연결한 color map 의 예를 보여줍니다.



Gray to Color Transformations

세 가지 함수 fR(x),fG(x),fB(x)f_R(x), f_G(x), f_B(x) 가 각각 빨강(R), 초록(G) 값을 할당합니다. 각 그레이 레벨 xx 에 대해 적절한 함수로 스케일링하여 색상을 생성합니다. 이 과정을 통해 그레이스케일 이미지의 시각적 표현을 크게 향상시킬 수 있습니다. 아래의 그래프는 각 색상(R, G, B) 값이 그레이 레벨 xx 에 따라 변하는 함수를 보여줍니다.

이를 통해 데이터를 시각화하는 데 있어서 단조로운 흑백 이미지를 다채롭게 변환하여 정보를 명확히 전달할 수 있습니다.



구현

Pseudo-coloring 기본 원리

b = io.imread('blocks.png')
io.imshow(b, cmap=plt.cm.jet)

이 코드는 blocks.png 라는 이미지를 불러온 후, jet 이라는 내장된 컬러맵을 사용해 색상을 적용합니다. jet 컬러맵은 빨강-노랑-초록-파랑으로 연결된 스펙트럼을 사용해 색상을 적용합니다. 결과적으로, 원래의 회색조 값이 색상 값으로 매핑됩니다.


사용자 정의 컬러맵 생성

x = np.array([[1, 1, 1, 0, 0],
			  [1, 0, 0, 1, 1],
              [0, 1, 0, 0, 1]])
vga = np.vstack((4 * x[0, :], 2 * x[1, :], 1 * x[2, :])) / 7.0
b16 = b / 16
myvga = clr.ListedColormap(vga)  # 16색 컬러맵 생성
plt.imshow(b16, cmap=myvga)

np.vstack 와 ListedColormap 을 활용해 사용자 정의 컬러맵을 생성하는 코드입니다. 컬러맵은 각 픽셀 값을 특정 색상으로 매핑합니다.


Python 내장 컬러맵

import matplotlib.pyplot as plt
print(plt.colormaps())  # 내장된 컬러맵 출력

Matplotlib 에서는 다양한 내장 컬러맵을 제공합니다(예: viridis, plasma, hot 등). 각 컬러맵은 다양한 데이터를 강조하거나 특정 분석에 적합하도록 설계되었습니다.


사용자 정의 컬러맵으로 이미지 처리

b = io.imread('blocks.png')
b4 = b / 64
mycolormap = mpl.colors.ListedColormap([[0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 0, 0]])
plt.imshow(b4, cmap=mycolormap)

입력 이미지를 특정 4가지 색상으로 매핑했습니다. 사용자가 직접 정의한 컬러맵을 활용하여, 특정 영역을 강조할 수 있습니다.


X-ray 이미지를 컬러코딩

첫 번째 이미지는 원본 흑백 X-ray 이미지입니다. 두 번째 이미지는 특정 픽셀 강도를 강조하기 위해 컬러로 코딩된 결과 이미지입니다. 이러한 과정은 균열을 더 명확히 보이도록 특정 색상을 할당할 때도 사용됩니다. 이 과정은 일반적으로 built-in colormap 또는 사용자 정의 색상 매핑을 통해 구현됩니다.




Processing of Color Images


기본 원리

방법 1: RGB 채널별 독립 처리

  • 접근법: 이미지의 RGB 채널을 각각 독립적으로 처리합니다.

  • 단계:
    Step 1) 이미지를 R, G, B 채널로 분리
    Step 2) 각 채널에 개별적으로 필터링 또는 변환 처리
    Step 3) 처리된 채널을 다시 합쳐 최종 이미지 생성

  • 한계점: 각 채널을 독립적으로 처리하기 때문에 채널 간 상호작용을 고려하지 않아, 색상이 왜곡될 가능성이 있습니다.


방법 2: YIQ 색 공간 변환

  • 접근법: RGB 이미지를 YIQ 색 공간으로 변환하여, 밝기 정보(Y)만 처리한 후 다시 RGB 로 변환합니다.

  • 단계:
    Step 1) RGB 이미지를 YIQ 로 변환하여 밝기(Y)와 색상 정보(I와 Q)를 분리
    Step 2) 밝기(Y)만 처리(예: contrast 향상)
    Step 3) 처리된 YIQ 이미지를 다시 RGB 로 변환

  • 장점: 색상 왜곡을 줄이고 밝기 정보를 더 효과적으로 조정할 수 있습니다.



히스토그램 평활화(HE)를 통한 대비(contrast) 향상

방법 1: 각 RGB 채널에 독립적으로 히스토그램 평활화 적용

import skimage.io as io
import skimage.exposure as exposure
import numpy as np

s = io.imread('color_sunset.png').astype('np.float64')
s2 = np.zeros_like(s)
for i in range(3):
	s2[:, :, i] = exposure.equalize_hist(s[:, :, i])
io.imshow(s2)

처리 과정: RGB 채널 각각에 독립적으로 히스토그램 평활화를 적용합니다.

결과: 이미지의 대비가 향상되지만, 채널을 개별적으로 처리하기 때문에 색상 밸런스가 깨질 수 있습니다.



방법 2: HSV 색 공간에서 밝기(V)만 평활화 적용

import skimage.color as co
import skimage.exposure as exposure

s = io.imread('color_sunset.png').astype('np.float64')
sh = co.rgb2hsv(s)
sh[:, :, 2] = exposure.equalize_hist(sh[:, :, 2])  # V 채널(밝기)만 조정
s2 = co.hsv2rgb(sh)
io.imshow(s2)

처리 과정:

  • 이미지를 HSV 색 공간으로 변환합니다.
  • 밝기(V) 채널에만 히스토그램 평활화 적용합니다.
  • 처리된 HSV 이미지를 다시 RGB로 변환합니다.

결과: 색상을 왜곡하지 않고 자연스럽게 밝기와 대비를 향상시킵니다.



Spatial Filtering

Low-pass filter 는 위에서 설명한 RGB의 각 성분에 적용하는 방법 1 이 더 효과적입니다. 반면에 high-pass filter방법 2 가 더 효과적입니다.



Noise Reduction

Salt-and-pepper noise 를 포함한 이미지를 더 선명하게 만듭니다.

방법 1: 각 RGB 성분에 개별적으로 노이즈 제거

방법 2: 밝기 성분만 처리하여 노이즈 제거

결과:

(a) 는 RGB 각각에 필터를 적용한 결과, (b) 는 밝기(V) 성분만 필터를 적용한 결과입니다. 방법 1 를 적용한 (a) 가 더 자연스럽고 선명한 결과를 보여줍니다.



Edge Detection

Edge detection 을 위해 두 가지 방법을 사용할 수 있습니다.

방법 1: 각 RGB 성분에 대해 edge detection 수행

방법 2: 밝기 성분만을 이용하여 edge detection 수행

결과:

방법 1 가 훨씬 edge 를 잘 검출하는 것을 확인할 수 있습니다.

profile
개발자 준비생

0개의 댓글