Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C언어로 RGB 색상 모델을 HSV 색상 모델로 변환하는 프로그램


정수 형태로 주어진 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)