반응형

1. 색상 공간 변환(RGB~HSI)

 

 

RGB와 HSI 색상 공간

 

1-(1) 색상 공간 변환(HSI) 수식

색상 공간 변환(HSI) 수식

1-(2) 색상 공간 변환(RGB) 수식

색상 공간 변환(RGB) 수식

 

 

2. 소스 코드

import os
import cv2
import numpy as np

def RGB_To_HSI(rgb):
    b = rgb[0]
    g = rgb[1]
    r = rgb[2]
    
    I = np.mean(rgb)
    
    #그레이스케일인 경우
    if (r==g==b):
        H=0
        S=0
    #컬러인 경우
    else:
        min_rgb = min(rgb)
        S=1-(min_rgb / I)
        
        temp = ((r-g) + (r-b)) / (2*np.sqrt( (r-g)*(r-g) + (r-b)*(g-b)))
        H = np.arccos(temp) * 180 / np.pi
        
        if b > g:
            H = 360 - H
        H /= 360
    
    return np.array([H, S, I], dtype=np.float32)

def HSI_To_RGB(hsi):
    h = hsi[0]
    s = hsi[1]
    i = hsi[2]
    #검은색의 경우
    if i == 0.0:
        R = G = B = 0
        return np.array([B,G,R], dtype=np.float32)
    #그레이스케일인 경우
    if s==0.0:
        R = G = B = i
        return np.array([B,G,R], dtype=np.float32)
    
    #각도 범위로 변경
    h *= 360
    if h <= 120:
        B = i*(1-s)
        R = i*(1+s*np.cos(h*np.pi/180)/np.cos((60-h)*np.pi/180))
        R = np.clip(R, 0.0, 1.0)
        G = 3*i-(R+B)
    elif h <= 240:
        h -= 120
        
        R = i*(1-s)
        G = i*(1+s*np.cos(h*np.pi/180)/np.cos((60-h)*np.pi/180))
        G = np.clip(G, 0.0, 1.0)
        B =  3*i-(R+G)        
    else:
        h -= 240
        
        G = i*(1-s)
        B = i*(1+s*np.cos(h*np.pi/180)/np.cos((60-h)*np.pi/180))
        B = np.clip(B, 0.0, 1.0)
        R =  3*i-(G+B)

    return np.array([B, G, R], dtype=np.float32)


#현재 실행되고 있는 경로 값을 얻어서 이미지 경로를 조합
cur_path = os.getcwd()
img_name='Lena_color.jpg'
image_path = os.path.join(cur_path, img_name)

#컬러로 이미지 읽기
img_src = cv2.imread(image_path, cv2.IMREAD_COLOR)

src_height = img_src.shape[0]
src_width = img_src.shape[1]
#rgb이미지를 hsi이미지로 변경 (0에서 1사이 값으로 스케일링)

img_src_temp = img_src/255
img_hsi = np.zeros(np.shape(img_src), dtype=np.float32)
for h in range(src_height):
    for w in range(src_width):
        img_hsi[h,w] = RGB_To_HSI(img_src_temp[h,w])
#변환한 hsi이미지를 채널별로 분리(0에서 255사이 값으로 스케일링)
img_h = np.uint8(np.clip(img_hsi[:,:,0]*255,0,255))
img_s = np.uint8(np.clip(img_hsi[:,:,1]*255,0,255))
img_i = np.uint8(np.clip(img_hsi[:,:,2]*255,0,255))
#원본 이미지와 분리한 채널을 출력
cv2.imshow('src', img_src)
cv2.imshow('h', img_h)
cv2.imshow('s', img_s)
cv2.imshow('i', img_i)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

3. 결과

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기