C RBG转HSV

RGB:

 

The RGB color model is an additive color model in which redgreen, and blue light are added together in various ways to reproduce a broad array of colors. The name of the model comes from the initials of the three additive primary colors, red, green, and blue.

RGB是一种加性颜色模式,由R(red)G(green)B(blue)的组合来显示不同的颜色。

 

HSV:

The two representations rearrange the geometry of RGB in an attempt to be more intuitive andperceptually relevant than the cartesian (cube) representation, by mapping the values into a cylinder loosely inspired by a traditional color wheel. The angle around the central vertical axis corresponds to "hue" and the distance from the axis corresponds to "saturation". These first two values give the two schemes the 'H' and 'S' in their names. The height corresponds to a third value, the system's representation of the perceived luminance in relation to the saturation.

HSV的产生是为了使颜色的表达更接近人的感官感觉。H(hue,色相,也就是颜色种类)S(saturate,饱和度,也就是颜色的纯度,相对于白色而言)V(value,亮度)。其中色相由上图圆锥上表面的角度表示,不同的角度对应不同的颜色。饱和度由水平面的半径表示,圆心处表示纯度为0,只剩下灰度(因为亮度为1是是白色,亮度是0是为黑色)。由z轴表示亮度,亮度为0表示黑色。

 

RGB向HSV的转化(在线转化:http://www.javascripter.net/faq/rgb2hsv.htm):

公式为(注:此处RGB的取值范围限于[0,1],若RGB使用整数0~255表示,则由RGB/255转化为小数):

 

h∈[0,360]        s,v∈[0,1](百分比)

 


h =
\begin{cases}
0^\circ & \mbox{if } max = min \\
60^\circ \times \frac{g - b}{max - min} + 0^\circ,   & \mbox{if } max = r \mbox{ and } g \ge b \\
60^\circ \times \frac{g - b}{max - min} + 360^\circ,   & \mbox{if } max = r \mbox{ and } g < b \\
60^\circ \times \frac{b - r}{max - min} + 120^\circ, & \mbox{if } max = g \\
60^\circ \times \frac{r - g}{max - min} + 240^\circ, & \mbox{if } max = b
\end{cases}

 

s =
\begin{cases}
0, & \mbox{if } max = 0 \\
\frac{max - min}{max} = 1 - \frac{min}{max}, & \mbox{otherwise}
\end{cases}

 

 v = max \,       (注意此时max是小数形式)        

 

 RGB&HSV对照表,注意RGB的范围是0~1(http://en.wikipedia.org/wiki/HSL_and_HSV

其他颜色表:http://www.ebaomonthly.com/window/photo/lesson/colorList.htm

 

RGB转HSV的C代码(RGB的范围为[0,255]):

#include<stdio.h>
#define uchar unsigned char

static int RGBtoHSV(uchar R , uchar G ,uchar B ,float  HSV[3]);//return 1 if succeed and save HSV in HSV[3]

static int isValid(uchar value);//if 0<=value<=255 return 1 else return 0
static uchar GetMax(uchar R , uchar G ,uchar B);
static uchar GetMin(uchar R , uchar G ,uchar B);


//implement
static int RGBtoHSV(uchar R , uchar G ,uchar B ,float  HSV[3])
{
    if(isValid(R)&&isValid(G)&&isValid(B))
    {
        int Max_value =  GetMax(R , G , B);
        int Min_value  = GetMin(R ,G ,B )  ;

        float H ;
        //compute H
        if(Max_value == Min_value)H = 0;
        else
        {
            if(Max_value==G)                      H =  60.0*(B-R)/(Max_value-Min_value) + 120;
            if(Max_value==B)                       H =  60.0*(R-G)/(Max_value-Min_value) +240;
            if(Max_value==R  &&  G>=B)H = 60.0*(G-B)/(Max_value-Min_value);
            if(Max_value==R  &&  G<   B)H  = 60.0*(G-B)/(Max_value-Min_value) + 360;
        }
        //end compute H
         //GOTO: ;
         float S;
        //compute S
        if(Max_value == 0)S = 0;
        else S = 1.0*(Max_value-Min_value)/Max_value;
        //end compute S
        float V = Max_value/255.0;

        HSV[0] = H;
        HSV[1]  = S;
        HSV[2] = V;
        return 1;
    }
    else
    {
        printf("Unvalid value !\n");
        return 0;
    }
}

static int isValid(uchar value)
{
    if(value>=0&&value<=255)return 1;
    return 0;
}

static uchar GetMax(uchar R , uchar G ,uchar B)
{
    uchar Max = G;
    if(R > G)Max = R;
    if(Max < B)Max = B;

    return Max;
}

static uchar GetMin(uchar R , uchar G ,uchar B)
{
    uchar Min = G;
    if(R < G)Min = R;
    if(Min > B)Min = B;

    return Min ;
}

#undef uchar

 

 

测试(为了便于与上图中的数据对照,这里RGB的取值范围为:[0,1]):

#include <stdio.h>
#include <stdlib.h>
#include"RGBtoHSV.c"
int main()
{
    float HSV[3] = {0};
    printf("RGB values([0,1]):");
    float fR,fG,fB;
    fflush(stdin);
  again:  printf("\nR:");
    scanf("%f",&fR);
    fflush(stdin);
    printf("\nG:");
    scanf("%f",&fG);
    fflush(stdin);
    printf("\nB:");
    scanf("%f",&fB);
    fflush(stdin);
    int R=(int)(fR*255);
    int G=(int)(fG*255);
    int B=(int)(fB*255);
    RGBtoHSV( R,G,B,HSV);
    printf("%d         %d              %d",R,G,B);
    printf("\nH:%f         S:%f           V:%f\n",HSV[0] , HSV[1] ,HSV[2]);
    printf("Press 'a' to compute again :");

    if('a'==getchar())goto again;
    else exit(0);
}

 

posted @ 2015-04-02 10:02  jiahu  阅读(897)  评论(0编辑  收藏  举报