HSV转RGB

HSV与RGB

一、RGB色彩模型

RGB(Red、Green、Blue)色彩模式是一种面向硬件的色彩模型,显示系统都采用RGB颜色模型来进行图像显示。RGB色彩模型属于加法混色原理,每种原色的数值越高,色彩就越亮,RGB都是0时是黑色,都是255时是白色。
RGB色彩模型表示直接,但是RGB数值和色彩的三属性没有直接的联系,不能揭示色彩之间的关系。

二、HSV色彩模型

HSV色彩模式应用最广泛的是一个倒圆锥模型,是一种面向用户感官的色彩模型,侧重与色彩表示。这是根据人的视觉系统对亮度的敏感度要强于色彩值这个生理特性而提出的颜色模型。
HSV(Hue、Saturation、Value)分别对应色相、饱和度、明度。

  • 色相H:用角度度量,取值范围为0°~360°,从红色开始按照逆时针方向计算,红色为0°,绿色为120°,蓝色为240°,黄色为60°,青色为180°,品红为300°,对应于绕圆柱的中心轴的角度。
  • 饱和度S:表示色彩的纯度,对应于离圆柱的中心轴的距离。数值越高颜色则深而艳,数值越低则颜色逐渐变灰,取值范围为0.0~1.0,白色的S=0。
  • 明度V:表示颜色的明亮程度。取值范围为0.0(黑色)~1.0(白色)。对应于绕圆柱的中心轴的高度,轴取值为自底部的黑色V=0到顶部的白色V=1。
    在这里插入图片描述
    在这里插入图片描述

三、HSV的应用

HSV模型在计算机图形应用中,常使用HSV色轮,其中色相表示为圆环,用一个独立的三角形来表示饱和度(S)和明度(V)。这个三角形的垂直轴表示饱和度,水平轴表示明度。在这种方式下,选择颜色可以首先在圆环中选择色相,在三角形中选择需要的饱和度和明度。

HSV模型还可以通过圆柱体来表示。色相沿着圆柱体的外圆周变化,饱和度沿着横截面的圆心的距离变化,明度沿着横截面底面到顶面的距离变化。
在这里插入图片描述

HSV与RGB互转

由于HSV是面向用户的色彩模型,而显示系统都采用面向硬件的RGB色彩模型,所以在控制硬件的时候,需要进行HSV与RGB的转换。
设 (r, g, b) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设 max 等价于 r, g 和 b中的最大者。设 min 等于这些值中的最小者。要找到在 HSV 空间中的 (h, s, v) 值,这里的 h ∈ [0, 360)是角度的色相角,而 s, v ∈ [0,1] 是饱和度和明度。
由于HSV与RGB在计算中都涉及到小数运算,转换会有精度损失。
HSV范围采用:H:0~360;S : 0~1000; V : 1000;
RGB的范围采用:R : 0~1000;G : 0~1000; B : 1000;

HSV2RGB 
/**
 * @brief: HSV change to RGB
 * @param {IN USHORT_T h -> range 0~360 }
 * @param {IN USHORT_T s -> range 0~1000}
 * @param {IN USHORT_T v -> range 0~1000}
 * @param {OUT USHORT_T *r -> R result,rang from 0~1000}
 * @param {OUT USHORT_T *g -> G result,rang from 0~1000}
 * @param {OUT USHORT_T *b -> B result,rang from 0~1000}
 * @retval: none
 */
VOID vLightToolHSV2RGB(IN USHORT_T h, IN USHORT_T s, IN USHORT_T v, OUT USHORT_T *r, OUT USHORT_T *g, OUT USHORT_T *b)
{
    INT_T i;
    FLOAT_T RGB_min, RGB_max;
    FLOAT_T RGB_Adj;
    INT_T difs;

    if(h >= 360) {
        h = 0;
    }
    
    RGB_max = v * 1.0f;
    RGB_min = RGB_max*(1000 - s) / 1000.0f;

    i = h / 60;
    difs = h % 60; /* factorial part of h */


    /* RGB adjustment amount by hue */
    RGB_Adj = (RGB_max - RGB_min)*difs / 60.0f;

    switch (i) {
        case 0:
            *r = (USHORT_T)RGB_max;
            *g = (USHORT_T)(RGB_min + RGB_Adj);
            *b = (USHORT_T)RGB_min;
            break;
            
        case 1:
            *r = (USHORT_T)(RGB_max - RGB_Adj);
            *g = (USHORT_T)RGB_max;
            *b = (USHORT_T)RGB_min;
            break;
            
        case 2:
            *r = (USHORT_T)RGB_min;
            *g = (USHORT_T)RGB_max;
            *b = (USHORT_T)(RGB_min + RGB_Adj);
            break;
            
        case 3:
            *r = (USHORT_T)RGB_min;
            *g = (USHORT_T)(RGB_max - RGB_Adj);
            *b = (USHORT_T)RGB_max;
            break;
            
        case 4:
            *r = (USHORT_T)(RGB_min + RGB_Adj);
            *g = (USHORT_T)RGB_min;
            *b = (USHORT_T)RGB_max;
            break;
            
        default:        // case 5:
            *r = (USHORT_T)RGB_max;
            *g = (USHORT_T)RGB_min;
            *b = (USHORT_T)(RGB_max - RGB_Adj);
            break;
    }

    if(*r > 1000) {
        *r = 1000;
    }

    if(*g > 1000) {
        *g = 1000;
    }

    if(*b > 1000) {
        *b = 1000;
    }
}
RGB2HSV 
/**
 * @brief: RGB change to HSV
 * @param {IN USHORT_T R -> R,rang from 0~1000}
 * @param {IN USHORT_T G -> G,rang from 0~1000}
 * @param {IN USHORT_T B -> B,rang from 0~1000}
 * @param {OUT USHORT_T H -> result, range 0~360}
 * @param {OUT USHORT_T S -> result, range 0~1000}
 * @param {OUT USHORT_T V -> result, range 0~1000}
 * @retval: none
 */
VOID vLightToolRGB2HSV(IN USHORT_T R, IN USHORT_T G, IN USHORT_T B, OUT USHORT_T *H, OUT USHORT_T *S, OUT USHORT_T *V)
{
    FLOAT_T r,g,b;
    FLOAT_T minRGB,maxRGB,deltaRGB;
    FLOAT_T h = 0,s = 0,v = 0;
     
    r = R / 1000.0f;
    g = G / 1000.0f;
    b = B / 1000.0f;

    minRGB = fLightToolGetMIN(r,fLightToolGetMIN(g,b));
    maxRGB = fLightToolGetMAX(r,fLightToolGetMAX(g,b));

    deltaRGB = maxRGB - minRGB;

    v = maxRGB;
    if(maxRGB != 0.0) {
        s = deltaRGB / maxRGB;
    } else {
        s = 0.0;
    }
    
    if(s <= 0.0) {
        h = -1.0f;
    } else {
        if(r == maxRGB) {
            h = (g-b) / deltaRGB;
        } else if (g == maxRGB) {
            h = 2.0 + (b-r) / deltaRGB;
        } else if (b == maxRGB) {
            h = 4.0 + (r-g) / deltaRGB;
        }
    }
    
    h = h * 60.0;
    if(h < 0.0) {
        h += 360;
    }

    *H = (USHORT_T)h;
    *S = (USHORT_T)(s * 1000);
    *V = (USHORT_T)(v * 1000);

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值