zoukankan      html  css  js  c++  java
  • 颜色空间RGB与HSV(HSL)的转换

    一般的3D编程只需要使用RGB颜色空间就好了,但其实美术人员更多的是使用HSV(HSL),因为可以方便的调整饱和度和亮度。

    有时候美术需要程序帮助调整饱和度来达到特定风格的渲染效果,这时候就需要转换颜色空间了。

    出处:http://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4

    HSL 和 HSV(也叫做 HSB)是对RGB 色彩空间中点的两种有关系的表示,它们尝试描述比 RGB 更准确的感知颜色联系,并仍保持在计算上简单。HSL 表示 hue(色相)、saturation(饱和度)、lightness(亮度),HSV 表示 hue、saturation、value(色调) 而 HSB 表示 hue、saturation、brightness(明度)。

    HSL 和 HSV 二者都把颜色描述在圆柱体内的点,这个圆柱的中心轴取值为自底部的黑色到顶部的白色而在它们中间是的灰色,绕这个轴的角度对应于“色相”,到这个轴的距离对应于“饱和度”,而沿着这个轴的距离对应于“亮度”,“色调”或“明度”。

    这两种表示在用目的上类似,但在方法上有区别。二者在数学上都是圆柱,但 HSV(色相,饱和度,明度)在概念上可以被认为是颜色的倒圆锥体(黑点在下顶点,白色在上底面圆心),HSL 在概念上表示了一个双圆锥体和圆球体(白色在上顶点,黑色在下顶点,最大横切面的圆心是半程灰色)。注意尽管在 HSL 和 HSV 中“色相”指称相同的性质,它们的“饱和度”的定义是明显不同的。

    因为 HSL 和 HSV 是设备依赖的 RGB 的简单变换,(hsl) 或 (hsv) 三元组定义的颜色依赖于所使用的特定红色绿色蓝色加法原色”。每个独特的 RGB 设备都伴随着一个独特的 HSL 和 HSV 空间。但是 (hsl) 或 (hsv) 三元组在被约束于特定 RGB 空间比如 sRGB 的时候就变成明确的了。

    HSV 模型在 1978 年由埃尔维·雷·史密斯创立。

    动机

    艺术家有时偏好使用 HSV 颜色模型而不选择 RGB 或 CMYK 模型,因为它类似于人类感觉颜色的方式。RGB 和 CMYK 分别是加法原色减法原色模型,以原色组合的方式定义颜色,而 HSV 以人类更熟悉的方式封装了关于颜色的信息:“这是什么颜色?深浅如何?明暗如何?”。HSL 颜色空间类似于 HSV,在某些方面甚至比它还好。

    [编辑]用途

    HSV 色轮允许用户快速的选择众多颜色。
    HSV 模型的圆锥表示适合于在一个单一物体中展示整个 HSV 色彩空间。

    HSV 模型通常用于计算机图形应用中。在用户必须选择一个颜色应用于特定图形元素各种应用环境中,经常使用 HSV 色轮。在其中,色相表示为圆环;可以使用一个独立的三角形来表示饱和度和明度。典型的,这个三角形的垂直轴指示饱和度,而水平轴表示明度。在这种方式下,选择颜色可以首先在圆环中选择色相,在从三角形中选择想要的饱和度和明度。

    HSV 模型的另一种可视方法是圆锥体。在这种表示中,色相被表示为绕圆锥中心轴的角度,饱和度被表示为从圆锥的横截面的圆心到这个点的距离,明度被表示为从圆锥 的横截面的圆心到顶点的距离。某些表示使用了六棱锥体。这种方法更适合在一个单一物体中展示这个 HSV 色彩空间;但是由于它的三维本质,它不适合在二维计算机界面中选择颜色。

    HSV 色彩空间还可以表示为类似于上述圆锥体的圆柱体,色相沿着圆柱体的外圆周变化,饱和度沿着从横截面的圆心的距离变化,明度沿着横截面到底面和顶面的距离而 变化。这种表示可能被认为是 HSV 色彩空间的更精确的数学模型;但是在实际中可区分出的饱和度和色相的级别数目随着明度接近黑色而减少。此外计算机典型的用有限精度范围来存储 RGB 值;这约束了精度,再加上人类颜色感知的限制,使圆锥体表示在多数情况下更实用。

    [编辑]HSL 与 HSV 的比较

    HSL 和 HSV 色彩空间比较。

    HSL 类似于 HSV。对于一些人,HSL 更好的反映了“饱和度”和“亮度”作为两个独立参数的直觉观念,但是对于另一些人,它的饱和度定义是错误的,因为非常柔和的几乎白色的颜色在 HSL 可以被定义为是完全饱和的。对于 HSV 还是 HSL 更适合于人类用户界面是有争议的。

    W3C 的 CSS3 规定声称“HSL 的优点是它对称于亮与暗(HSV 就不是这样)…”,这意味着:

    • 在 HSL 中,饱和度分量总是从完全饱和色变化到等价的灰色(在 HSV 中,在极大值 V 的时候,饱和度从全饱和色变化到白色,这可以被认为是反直觉的)。
    • 在 HSL 中,亮度跨越从黑色过选择的色相到白色的完整范围(在 HSV 中,V 分量只走一半行程,从黑到选择的色相)。

    在 软件中,通常以一个线性或圆形色相选择器和在其中为选定的色相选取饱和度和明度/亮度的一个二维区域(通常为方形或三角形)形式提供给用户基于色相的颜色 模型(HSV 或 HSL)。通过这种表示,在 HSV 和 HSL 之间的区别就无关紧要了。但是很多程序还允许你通过线性滑块或数值录入框来选择颜色的明度/亮度,而对于这些控件通常使用要么 HSL 要么 HSV(而非二者)。HSV 传统上更常用。下面是一些例子:

    GIMP 支持在 HSV 色彩空间内的选取颜色的多种方法,包括带有色相滑块的色轮和色方。

    [编辑]与其他颜色模型的比较

    HSV 颜色空间在技术上不支持到辐射测定中测量的物理能量谱密度的一一映射。所以一般不建议做在 HSV 坐标和物理光性质如波长振幅之间的直接比较。

    [编辑]形式定义

    HSL 和 HSV 在数学上定义为在 RGB 空间中的颜色的 RG 和 B 的坐标的变换。

    [编辑]从 RGB 到 HSL 或 HSV 的转换

    设 (rgb) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设 max 等价于 rg 和 b 中的最大者。设 min 等于这些值中的最小者。要找到在 HSL 空间中的 (hsl) 值,这里的 h ∈ [0, 360)是角度的色相角,而 sl ∈ [0,1] 是饱和度和亮度,计算为:

    h =egin{cases}0^circ & mbox{if } max = min \60^circ 	imes frac{g - b}{max - min} + 0^circ,   & mbox{if } max = r mbox{ and } g ge b \60^circ 	imes frac{g - b}{max - min} + 360^circ,   & mbox{if } max = r mbox{ and } g < b \60^circ 	imes frac{b - r}{max - min} + 120^circ, & mbox{if } max = g \60^circ 	imes frac{r - g}{max - min} + 240^circ, & mbox{if } max = bend{cases}
    l = egin{matrix} frac{1}{2} end{matrix} (max + min)
    s = egin{cases}0 & mbox{if } l = 0 mbox{ or } max = min \frac{max-min}{max+min} = frac{max-min}{2l}, & mbox{if } 0  frac{1}{2}end{cases}


    h 的值通常规范化到位于 0 到 360°之间。而 h = 0 用于 max = min 的(就是灰色)时候而不是留下 h 未定义。

    HSL 和 HSV 有同样的色相定义,但是其他分量不同。HSV 颜色的 s 和 v 的值定义如下:

     

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

    [编辑]从 HSL 到 RGB 的转换

    给定 HSL 空间中的 (hsl) 值定义的一个颜色,带有 h 在指示色相角度的值域 [0, 360)中,分别表示饱和度和亮度的s 和 l 在值域 [0, 1] 中,相应在 RGB 空间中的 (rgb) 三原色,带有分别对应于红色、绿色和蓝色的 rg 和 b 也在值域 [0, 1] 中,它们可计算为:

    首先,如果 s = 0,则结果的颜色是非彩色的、或灰色的。在这个特殊情况,rg 和 b 都等于 l。注意 h 的值在这种情况下是未定义的。

    当 s ≠ 0 的时候,可以使用下列过程:[1]

     

    q=egin{cases}l 	imes (1+s), & mbox{if } l < frac{1}{2} \l+s-(l 	imes s), & mbox{if } l ge frac{1}{2}end{cases}
    p = 2 	imes l - q \,
    h_k = {h over 360} \, h 规范化到值域 [0,1)内)
    t_R = h_k+frac{1}{3} \,
    t_G = h_k \,
    t_B = h_k-frac{1}{3} \,
    mbox{if } t_C < 0 
ightarrow t_C = t_C + 1.0 quad mbox{for each}\,C in {R,G,B}
    mbox{if } t_C > 1 
ightarrow t_C = t_C - 1.0 quad mbox{for each}\,C in {R,G,B}


    对于每个颜色向量 Color = (ColorRColorGColorB) = (rgb),

     

    {Color}_C =egin{cases}p+ left((q-p) 	imes 6 	imes t_C
ight), & mbox{if } t_C < frac{1}{6}  \q, & mbox{if } frac{1}{6} le t_C < frac{1}{2}  \p+left((q-p) 	imes 6 	imes (frac{2}{3} - t_C) 
ight), & mbox{if } frac{1}{2} le t_C < frac{2}{3} \p, & mbox{otherwise }end{cases}
    mbox{for each}\,C in {R,G,B}

    [编辑]从 HSV 到 RGB 的转换

    类似的,给定在 HSV 中 (hsv) 值定义的一个颜色,带有如上的 h,和分别表示饱和度和明度的 s 和 v 变化于 0 到 1 之间,在 RGB 空间中对应的 (rgb) 三原色可以计算为:

    h_i equiv leftlfloor frac{h}{60} 
ight
floor pmod{6}
    f = frac{h}{60} - h_i
    p = v 	imes (1 - s) \,
    q = v 	imes (1 - f 	imes s) \,
    t = v 	imes (1 - (1 - f) 	imes s) \,


    对于每个颜色向量 (rgb),

     

    (r, g, b) = egin{cases}(v, t, p), & mbox{if } h_i = 0  \(q, v, p), & mbox{if } h_i = 1  \(p, v, t), & mbox{if } h_i = 2  \(p, q, v), & mbox{if } h_i = 3  \(t, p, v), & mbox{if } h_i = 4  \(v, p, q), & mbox{if } h_i = 5  \end{cases}

    [编辑]例子

    展示的 RGB 值的范围是 0.0 到 1.0。

  • 相关阅读:
    c# 类型转换符的重载
    C# 串口读写
    STM32 Keil C++编写单片机程序
    C# 静态构造函数的使用
    MvvMlight 学习之 SimpleIoc
    STM32 之 DMA
    STM32 之 SysTick
    突然发现用PHP做多条件模糊查询很简单
    discuz代码转为html代码
    Discuz!开发之HTML转Discuz代码(bbcode)函数html2bbcode()
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4952723.html
Copyright © 2011-2022 走看看