HSV色彩属性

HSV色彩属性模式是根据色彩的三个基本属性:色相饱和度明度来 确定颜 色的一种方法。

  • 色相(H)是色彩的基本属性,就是平常所说的颜色名 称,如红 色黄色等,依照在右图的标准色轮上的位置,取0-360度的数值。(也有用0 –100%的方法确定的)。
  • 饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取0-100%的数值。
  • 明度(V)也叫“亮度”,取0-100%。

这种模式是 1978年 由 Alvy Ray Smith 创立的,它是三原色光模式的一种非线性变换。

算法核心是这样的

Vector3f HSV2RGB(const Vector3f& hsv)
{
    //先根据Hue计算出一个"纯的亮的颜色"
    Vector3f hueColor = GetColorByHue(hsv.h);

    //然后用Sat和Value做两次线性插值,Sat越高颜色越纯,越低会使颜色越靠近灰色,Value控制亮度。 
    return lerp<Vector3f>(0, lerp<Vector3f>(1, hueColor, hsv.s), hsv.v);

// hue应该是属于[0,1),但有时也认为属于[0,1]
// 其实影响不大,我这里统一处理了
Vector3f GetColorByHue(float hue)
{
    Vector3f color;
    hue = max(0.0f, min(hue, 1.0f));
    float hue6 = hue*6.0f;
    int z = min((int)hue6, 5);
    float f = hue6 - z;
    //可以想象一个圆,hue值与圆周上的点一一对应
    //圆周被均分成6段,每段只引起一个RGB分量变化
    switch(int(hue*6.0f))
    {
    case 0:
        color.r = 1.0f;
        color.g = f;
        color.b = 0.0f;
        break;
    case 1:
        color.r = 1.0f - f;
        color.g = 1.0f;
        color.b = 0.0f;
        break;
    case 2:
        color.r = 0.0f;
        color.g = 1.0f;
        color.b = f;
        break;
    case 3:
        color.r = 0.0f;
        color.g = 1.0f - f;
        color.b = 1.0f;
        break;
    case 4:
        color.r = f;
        color.g = 0.0f;
        color.b = 1.0f;
        break;
    case 5:
    default:
        color.r = 1.0f;
        color.g = 0.0f;
        color.b = 1.0f - f;
    }
    return color;
}


#include <iostream>
#include <cmath>
using  namespace std;

struct Vector3f
{
    Vector3f(){}
    Vector3f( const Vector3f& v):x(v.x),y(v.y),z(v.z){}
    Vector3f( float f):x(f),y(f),z(f){}
    Vector3f( float x, float y, float z):x(x),y(y),z(z){}

    Vector3f  operator + ( const Vector3f& v)  const
    {
         return Vector3f(x+v.x, y+v.y, z+v.z);
    }

    Vector3f  operator - ( const Vector3f& v)  const
    {
         return Vector3f(x-v.x, y-v.y, z-v.z);
    }

    Vector3f  operator * ( const Vector3f& v)  const
    {
         return Vector3f(x*v.x, y*v.y, z*v.z);
    }

    Vector3f  operator / ( const Vector3f& v)  const
    {
         return Vector3f(x/v.x, y/v.y, z/v.z);
    }

    union{
         struct{ float x,y,z;};
         struct{ float r,g,b;};
         struct{ float h,s,v;};
    };
};

Vector3f  operator + ( float f,  const Vector3f& v){  return Vector3f(f+v.x, f+v.y, f+v.z);}
Vector3f  operator - ( float f,  const Vector3f& v){  return Vector3f(f-v.x, f-v.y, f-v.z);}
Vector3f  operator * ( float f,  const Vector3f& v){  return Vector3f(f*v.x, f*v.y, f*v.z);}
Vector3f  operator / ( float f,  const Vector3f& v){  return Vector3f(f/v.x, f/v.y, f/v.z);}

template <typename T>
T lerp( const T& x,  const T& y,  const T& s)
{
     return x*(1-s) + y*s;
}

//  hue应该是属于[0,1),但有时也认为属于[0,1]
//  其实影响不大,我这里统一处理了
Vector3f GetColorByHue( float hue)
{
    Vector3f color;
    hue = max(0.0f, min(hue, 1.0f));
     float hue6 = hue*6.0f;
     int z = min(( int)hue6, 5);
     float f = hue6 - z;
     // 可以想象一个圆,hue与圆周上的点一一对应
    
// 圆周被均分成6段,每段只引起一个RGB分量变化
     switch( int(hue*6.0f))
    {
     case 0:
        color.r = 1.0f;
        color.g = f;
        color.b = 0.0f;
         break;
     case 1:
        color.r = 1.0f - f;
        color.g = 1.0f;
        color.b = 0.0f;
         break;
     case 2:
        color.r = 0.0f;
        color.g = 1.0f;
        color.b = f;
         break;
     case 3:
        color.r = 0.0f;
        color.g = 1.0f - f;
        color.b = 1.0f;
         break;
     case 4:
        color.r = f;
        color.g = 0.0f;
        color.b = 1.0f;
         break;
     case 5:
     default:
        color.r = 1.0f;
        color.g = 0.0f;
        color.b = 1.0f - f;
    }
     return color;
}

Vector3f HSV2RGB( const Vector3f& hsv)
{
    Vector3f hueColor = GetColorByHue(hsv.h);
     return hsv.v * lerp<Vector3f>(1, hueColor, hsv.s);
     // return lerp<Vector3f>(0, lerp<Vector3f>(1, hueColor, hsv.s), hsv.v);
}

int main()

    printf("HSV<360,256,256>->RGB<256,256,256>\n");
     int h,s,v;
     while(scanf("%d%d%d", &h, &s, &v)!=EOF)
    {
        Vector3f hsv = Vector3f(h/360.0f,s/256.0f,v/256.f);
        Vector3f rgb = HSV2RGB(hsv);
        printf("RGB(%d,%d,%d)\n", ( int)(rgb.r*256), ( int)(rgb.g*256), ( int)(rgb.b*256));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值