정수 형태로 주어진 RGB 색상 값이 있을 때, 이를 변환하여 적절한 HSV 색상 값을 구하는 것이 이번 글의 목표입니다.
RGB 색상 모델이란?
RGB 색상 모델은 빨강(Red), 초록(Green), 파랑(Blue)의 세 가지 색상으로 구성됩니다. RGB 모델은 디스플레이 기술 분야에서 가장 널리 사용되는 색상 모델로, 가산 혼합(additive) 방식에 기반합니다. 즉, 세 가지 색상을 서로 다른 강도로 조합하여 디스플레이 장치 위에 수백만 가지의 다양한 색상을 표현할 수 있습니다.
HSV 색상 모델이란?
HSV 색상 모델은 색조(Hue), 채도(Saturation), 명도(Value)로 구성되며, HSB(Hue, Saturation, Brightness)라고도 불립니다. HSV는 RGB 색상 모델을 다른 관점에서 표현한 방식으로, 인간의 시각이 색상을 인식하는 특성과 일치하도록 고안되었습니다. 자연스러운 색 체계를 제공하기 때문에 예술가들 사이에서 특히 많이 활용되는 색상 모델입니다. HSV의 세 속성은 가산 및 감산 방식 모두로 표현할 수 있습니다.
프로그램에서 수행해야 할 작업
사용자로부터 RGB 모델의 값을 입력받은 후, 수학적 계산을 거쳐 HSV 색상 모델 값으로 변환하여 출력해야 합니다.
예제
입력: r = 31, g = 52, b = 29
출력: h s v = (114.782608, 44.230770, 20.392157)
입력: r = 129, g = 88, b = 47
출력: h s v = (30.000000, 63.565895, 50.588238)
주어진 문제를 해결하기 위해 사용할 접근 방법은 다음과 같습니다.
- 빨강(r), 초록(g), 파랑(b) 세 가지 색상 값을 입력받습니다.
- 모든 색상 값을 255로 나누어 0~1 범위로 정규화합니다.
- cmax(최댓값), cmin(최솟값), 그리고 두 값의 차이(diff)를 계산합니다.
- 색조(Hue) 계산 조건 확인:
- cmax와 cmin이 같으면 Hue(h)는 0입니다.
- cmax가 빨강(r)과 같으면 Hue(h) = (60 * ((g – b) / diff) + 360) % 360
- cmax가 초록(g)과 같으면 Hue(h) = (60 * ((b – r) / diff) + 120) % 360
- cmax가 파랑(b)과 같으면 Hue(h) = (60 * ((r – g) / diff) + 240) % 360
- 채도(Saturation) 계산:
- cmax가 0이면 Saturation(s) = 0
- cmax가 0이 아니면 Saturation(s) = (diff / cmax) * 100
- 명도(Value) 계산:
- Value(v) = cmax * 100
알고리즘
시작
1단계 -> 함수 float max(float a, float b, float c)
Return (a > b)? (a > c ? a : c) : (b > c ? b : c)
2단계 -> 함수 float min(float a, float b, float c)
Return (a < b)? (a < c ? a : c) : (b < c ? b : c)
3단계 -> 함수 int rgb_to_hsv(float r, float g, float b)
float h, s, v 선언
r = r / 255.0 설정
g = g / 255.0 설정
b = b / 255.0 설정
cmax = max(r, g, b) 설정
cmin = min(r, g, b) 설정
diff = cmax - cmin 설정
만약 cmax == cmin 이면,
h = 0 설정
종료
그렇지 않고 cmax == r 이면,
h = fmod((60 * ((g - b) / diff) + 360), 360.0) 설정
종료
그렇지 않고 cmax == g 이면,
h = fmod((60 * ((b - r) / diff) + 120), 360.0) 설정
종료
그렇지 않고 cmax == b 이면,
h = fmod((60 * ((r - g) / diff) + 240), 360.0) 설정
종료
만약 cmax == 0 이면,
s = 0 설정
종료
그 외의 경우
s = (diff / cmax) * 100 설정
종료
v = cmax * 100;
h, s, v 출력
4단계 -> int main(int argc, char const *argv[])
r = 45, g = 215, b = 0으로 선언 및 초기화
rgb_to_hsv(r, g, b) 함수 호출
종료
예제 코드
#include <stdio.h>
#include <math.h>
float max(float a, float b, float c) {
return ((a > b)? (a > c ? a : c) : (b > c ? b : c));
}
float min(float a, float b, float c) {
return ((a < b)? (a < c ? a : c) : (b < c ? b : c));
}
int rgb_to_hsv(float r, float g, float b) {
// R, G, B 값을 255로 나누어
// 범위를 0..255에서 0..1로 변경합니다.
float h, s, v;
r /= 255.0;
g /= 255.0;
b /= 255.0;
float cmax = max(r, g, b); // r, g, b 중 최댓값
float cmin = min(r, g, b); // r, g, b 중 최솟값
float diff = cmax - cmin; // cmax와 cmin의 차이
if (cmax == cmin)
h = 0;
else if (cmax == r)
h = fmod((60 * ((g - b) / diff) + 360), 360.0);
else if (cmax == g)
h = fmod((60 * ((b - r) / diff) + 120), 360.0);
else if (cmax == b)
h = fmod((60 * ((r - g) / diff) + 240), 360.0);
// cmax가 0인 경우
if (cmax == 0)
s = 0;
else
s = (diff / cmax) * 100;
// 명도(v) 계산
v = cmax * 100;
printf("h s v=(%f, %f, %f)\n", h, s, v);
return 0;
}
// 메인 함수
int main(int argc, char const *argv[]) {
int r = 45, g = 215, b = 0;
rgb_to_hsv(r, g, b);
return 0;
}
출력 결과
h s v=(107.441864, 100.000000, 84.313728)