范围值为伪彩色

时间:2012-06-05 16:25:48

标签: python colors floating-point gradient

我有一些浮点数(在Python中),范围从0到100.我想创建一个伪彩色图像,使颜色从绿色(对应于0)变为红色(100)。这类似于matplotlib的pcolor。但是,我不想使用pcolor。

是否有类似pseudocolorForValue(val,(minval,maxval))的函数返回与val的伪色值对应的RGB三元组?此外,此功能是否具有灵活性,可以选择是显示从绿色到红色还是从红色到绿色的颜色?

谢谢, NIK

3 个答案:

答案 0 :(得分:16)

您可以编写自己的函数,将值转换为0 ... 100→0 ... 120度,然后将该值用作HSV(或HLS)颜色空间中颜色的H(或角度)。然后可以将其转换为RGB颜色以用于显示目的。线性解释的颜色在这个颜色空间中计算时通常看起来更好:这是HSV颜色空间的样子:

hsv colorspace diagram

<强>更新

好消息,我惊喜地发现Python在其内置colorsys模块中具有色彩空间转换例程(它们实际上意味着“包含电池”)。有趣的是,它创建了一个功能,可以完成我所描述的相当简单的功能,如下所示:

from colorsys import hsv_to_rgb

def pseudocolor(val, minval, maxval):
    """ Convert val in range minval..maxval to the range 0..120 degrees which
        correspond to the colors Red and Green in the HSV colorspace.
    """
    h = (float(val-minval) / (maxval-minval)) * 120

    # Convert hsv color (h,1,1) to its rgb equivalent.
    # Note: hsv_to_rgb() function expects h to be in the range 0..1 not 0..360
    r, g, b = hsv_to_rgb(h/360, 1., 1.)
    return r, g, b

if __name__ == '__main__':
    steps = 10

    print('val       R      G      B')
    for val in range(0, 100+steps, steps):
        print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format(
                                                val, *pseudocolor(val, 0, 100)))

输出:

val       R      G      B
  0 -> (1.000, 0.000, 0.000)
 10 -> (1.000, 0.200, 0.000)
 20 -> (1.000, 0.400, 0.000)
 30 -> (1.000, 0.600, 0.000)
 40 -> (1.000, 0.800, 0.000)
 50 -> (1.000, 1.000, 0.000)
 60 -> (0.800, 1.000, 0.000)
 70 -> (0.600, 1.000, 0.000)
 80 -> (0.400, 1.000, 0.000)
 90 -> (0.200, 1.000, 0.000)
100 -> (0.000, 1.000, 0.000)

以下是显示其输出结果的示例:

sample showing color interpolation in HSV colorspace

我认为您可能会发现颜色比我的其他答案更好。

<强>泛化:

可以将此功能修改为更通用,因为它可以使用其他颜色,而不仅仅是当前硬编码的红色和绿色。

以下是如何做到这一点:

def pseudocolor(val, minval, maxval, start_hue, stop_hue):
    """ Convert val in range minval..maxval to the range start_hue..stop_hue
        degrees in the HSV colorspace.
    """
    h = (float(val-minval) / (maxval-minval)) * (stop_hue-start_hue) + start_hue

    # Convert hsv color (h,1,1) to its rgb equivalent.
    # Note: hsv_to_rgb() function expects h to be in the range 0..1 not 0..360
    r, g, b = hsv_to_rgb(h/360, 1., 1.)
    return r, g, b

if __name__ == '__main__':
    # angles of common colors in hsv colorspace
    RED, YELLOW, GREEN, CYAN, BLUE, MAGENTA = range(0, 360, 60)
    steps = 10

    print('val       R      G      B')
    for val in range(0, 100+steps, steps):
        print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format(
                val, *pseudocolor(val, 0, 100, YELLOW, BLUE)))

结果:

sample showing color interpolation in HSV colorspace between yellow and blue

答案 1 :(得分:6)

虽然不如在HLS或HSV颜色空间中插值H那么漂亮,但实现方法更简单的方法是编写一个函数,将单个值映射为三个组件,对应于完全{{1}之间的线性插值颜色在RGB颜色空间中完全绿色red (1,0,0)

这就是我的意思:

(0,1,0)

输出:

def pseudocolor(val, minval, maxval):
    """ Convert value in the range minval...maxval to a color between red
        and green.
    """
    f = float(val-minval) / (maxval-minval)
    r, g, b = 1-f, f, 0.
    return r, g, b

if __name__ == '__main__':
    steps = 10
    print('val       R      G      B')
    for val in xrange(0, 100+steps, steps):
        print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format(
                    val, *pseudocolor(val, 0, 100)))

您可以根据需要转换浮点r,g,b分量,例如转换为0..255范围内的整数。

以下是显示其输出结果的示例:

image showing interpolation in RGB colorspace

如果您想从绿色变为红色,只需反转函数中 r g 的计算。如果没有太多额外的努力,您可以概括这个概念,以允许任何两种给定颜色之间的线性插值。

以下是如何做到的:

val       R      G      B
  0 -> (1.000, 0.000, 0.000)
 10 -> (0.900, 0.100, 0.000)
 20 -> (0.800, 0.200, 0.000)
 30 -> (0.700, 0.300, 0.000)
 40 -> (0.600, 0.400, 0.000)
 50 -> (0.500, 0.500, 0.000)
 60 -> (0.400, 0.600, 0.000)
 70 -> (0.300, 0.700, 0.000)
 80 -> (0.200, 0.800, 0.000)
 90 -> (0.100, 0.900, 0.000)
100 -> (0.000, 1.000, 0.000)

使用提供的颜色输出样本:

image showing interpolation in RGB colorspace with different colors

答案 2 :(得分:3)

您可以直接访问matplolib's built-in colormaps,这正是pcolor用来确定其颜色映射的内容。每个映射都采用[0,1]范围内的浮点数,并返回范围为[0,1]的浮点数的4元素元组,其中包含组件(R,G,B,A)。下面是一个使用标准jet色彩映射返回RGBA元组的函数示例:

from matplotlib import cm

def pseudocolor(val, minval, maxmal):
    # Scale val to be in the range [0, 1]
    val = (val - minval) / (maxval - minval)
    # Return RGBA tuple from jet colormap
    return cm.jet(val)

pseudocolor(20, 0, 100)
# Returns: (0.0, 0.3, 1.0, 1.0)

pseudocolor(80, 0, 100)
# Returns: (1.0, 0.4074, 0.0, 1.0)

这将映射到下图中显示的颜色范围。

enter image description here

此方法的一个便捷功能是,您可以通过将cm.jet更改为cm.rainbowcm.nipy_spectral,{{1}轻松切换到matplotlib colormaps中的任何一个等等。