RGB를 HSI로 변환

RGB를 HSI로 변환

Author : Jino Bae / Send Mail

Image Editor를 만들때 RGB를 조절하여 색상을 조절하는 기능을 구현하고 HSI를 조절하여 색상을 조절하는 기능을 추가하려고 했으나 관련 지식이 너무나 부족했고, 기본적으로 Hue를 변경할 수 있게해야 하는 합당한 이유를 찾을 수 없어서 만들지 않았었다.

오늘 HSI에 대해서 배우는데 갑자기 묵혀가고 있던 프로그램이 생각나 해당 기능을 추가해 보려고 한다. 하지만 여전히 Hue에 대해선 잘 모르겠다. 색상이 각도로 표시되고 각도를 변경하는데 … 음 … 왜 해야하는 거지? 일단 채도와 명도에 대한 변경은 있어야 하니까 넘어가자.


HSI란?

RGB는 인간의 눈에 있는 간상세포가 구분할 수 있는 색상 단위이다. 그래서 색상을 표현할때 대부분 RGB값을 사용하여 표현하지만 밝기나 채도에 대한 구분이 어렵다. HSI는 좀 더 인간에게 친화적인 색상구조다.


HSI의 구성요소

HSI 구성

  • Hue : 색상(색상의 각도)
  • Saturation : 채도(색상의 좌우이동)
  • Intensity : 명도(색상의 상하이동)

우선 나의 목표는 사용자가 Hue, Saturation, Intensity 값을 각각 변경하면 기존 RGB 값을 가져와 HSI로 변경한 후 값을 수정하여 다시 RGB로 만들어 줄 것이다. 값을 변경하는데 사용되는 식은 다음과 같다.

식


RGB to Hue

다른건 이해가 잘 가는데 Hue의 변환방법은 약간 생소했다. 그래서 스택 오버플로우에서 관련 내용을 찾아 보았다. 참고

  1. Convert the RGB values to the range 0-1, this can be done by dividing the value by 255 for 8-bit color depth (r,g,b - are given values):
    1
    2
    3
    
    R = r / 255 = 0.09
    G = g / 255 = 0.38
    B = b / 255 = 0.46
    
  2. Find the minimum and maximum values of R, G and B.
  3. Depending on what RGB color channel is the max value. The three different formulas are:
    1
    2
    3
    
    If Red is max, then Hue = (G-B)/(max-min)
    If Green is max, then Hue = 2.0 + (B-R)/(max-min)
    If Blue is max, then Hue = 4.0 + (R-G)/(max-min)
    

이렇게 보니 조금은 알 것 같다. 최대값과 최솟값을 찾은 뒤 가장 큰 색상값에 따라 알맞은 식을 적용해 주면 된다. 먼저 Qt에서 무작정 따라해 보도록 해야겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
rgb = image.pixel(x,y);
RGB[0] = qRed(rgb) / 255;
RGB[1] = qGreen(rgb) / 255;
RGB[2] = qBlue(rgb) / 255;

double min = 999, max = 0;
int max_index = 0;
for(int i=0;i<3;i++) {
    if(min > RGB[i]) min = RGB[i];
    if(max < RGB[i]) { max = RGB[i]; max_index = i; }
}

switch(max_index) {
    case 0: // Red is max
        hue = (RGB[1]-RGB[2])/(max-min);
        break;
    case 1: // Green is max
        hue = 2.0 +  (RGB[3]-RGB[1])/(max-min);
        break;
    case 2: // Blue is max
        hue = 4.0 + (RGB[0]-RGB[1])/(max-min);
        break;
}

일단 RGB가 Hue로 변경은 되었다. 그 다음 Hue를 조절한 값 만큼 더하거나 빼고 다시 RGB로 변경해야 할 것이다. 지금 다루는 것은 RGB를 HSI로 변경하는 작업이므로 PASS.


RGB to Saturation

1
2
3
4
5
6
7
8
9
rgb = image.pixel(x,y);
RGB[0] = qRed(rgb);
RGB[1] = qGreen(rgb);
RGB[2] = qBlue(rgb);
double min = 999;
for(int i=0;i<3;i++) {
    if(min > RGB[i]) min = RGB[i];
}
saturation = 1 - 3/(RGB[0]+RGB[1]+RGB[2]) * min;

RGB to Intensity

1
2
3
4
5
rgb = image.pixel(x,y);
r = qRed(rgb);
g = qGreen(rgb);
b = qBlue(rgb);
intensity = (r+g+b)/3;

Jino Bae
WRITTEN BY

Jino Bae

Digital is a purely man-made playground. That's why I like.
im@baejino.com


comments powered by Disqus