天天看點

RGB 和 HSV 互相轉換算法

一、簡介

        RGB 是我們接觸最多的顔色空間,分别為紅色(R),綠色(G)和藍色(B)。HSV 是用色調H,飽和度S,明亮度V來描述顔色的變化,H取值範圍為0°~360°,從紅色開始按逆時針方向計算,紅色為0°,綠色為120°,藍色為240°。飽和度S越高,顔色則深而豔。光譜色的白光成分為0,飽和度達到最高。通常取值範圍為0%~100%,值越大,顔色越飽和。H表示顔色明亮的程度,對于光源色,明度值與發光體的光亮度有關;對于物體色,此值和物體的透射比或反射比有關。通常取值範圍為0%(黑)到100%(白)。

二、從RGB轉換到HSV

  • 設 (r, g, b) 分别是一個顔色的紅、綠和藍坐标,它們的值是在 0 到 1 之間的實數
  • 設 max 等于 r, g, b 中的最大者
  • 設 min 等于 r, g, b 中的最小者
RGB 和 HSV 互相轉換算法

轉換代碼如下:

float retmax(float a,float b,float c)//求最大值
{
    float max = 0;
    max = a;
    if(max<b)
        max = b;
    if(max<c)
        max = c;
    return max;
}
float retmin(float a,float b,float c)//求最小值
{
    float min = 0;
    min = a;
    if(min>b)
        min = b;
    if(min>c)
        min = c;
    return min;
}
//R,G,B參數傳入範圍(0~100)
//轉換結果h(0~360),s(0~100),v(0~100)
void rgb_to_hsv(float *h,float *s,float *v,float R,float G,float B)
{
    float max = 0,min = 0;
    R = R/100;
    G = G/100;
    B = B/100;

    max = retmax(R,G,B);
    min = retmin(R,G,B);
    *v = max;
    if(max == 0)
        *s = 0;
    else
        *s = 1 - (min/max);

    if(max == min)
        *h = 0;
    else if(max == R && G>=B)
        *h = 60*((G-B)/(max-min));
    else if(max == R && G<B)
        *h = 60*((G-B)/(max-min)) + 360;
    else if(max == G)
        *h = 60*((B-R)/(max-min)) + 120;
    else if(max == B)
        *h = 60*((R-G)/(max-min)) + 240;

    *v = *v * 100;
    *s = *s * 100;
}
           

三、從HSV轉換到RGB

1、轉換公式如下:

RGB 和 HSV 互相轉換算法

2、轉換代碼如下:

//參數入參範圍h(0~360),s(0~100),v(0~100),這裡要注意,要把s,v縮放到0~1之間
//轉換結果R(0~100),G(0~100),B(0~100),如需轉換到0~255,隻需把後面的乘100改成乘255
void hsv_to_rgb(int h,int s,int v,float *R,float *G,float *B)
{
    float C = 0,X = 0,Y = 0,Z = 0;
    int i=0;
    float H=(float)(h);
    float S=(float)(s)/100.0;
    float V=(float)(v)/100.0;
    if(S == 0)
        *R = *G = *B = V;
    else
    {
        H = H/60;
        i = (int)H;
        C = H - i;

        X = V * (1 - S);
        Y = V * (1 - S*C);
        Z = V * (1 - S*(1-C));
        switch(i){
            case 0 : *R = V; *G = Z; *B = X; break;
            case 1 : *R = Y; *G = V; *B = X; break;
            case 2 : *R = X; *G = V; *B = Z; break;
            case 3 : *R = X; *G = Y; *B = V; break;
            case 4 : *R = Z; *G = X; *B = V; break;
            case 5 : *R = V; *G = X; *B = Y; break;
        }
    }
    *R = *R *100;
    *G = *G *100;
    *B = *B *100;
}