将RGB三元组列表排序为频谱

Jas*_*ram 16 python hsv spectrum color-space python-imaging-library

我有一个RGB三元组列表,我想以这样的方式绘制它们,使它们形成像光谱一样的东西.

我把它们转换成了人们似乎推荐的HSV.

from PIL import Image, ImageDraw
import colorsys

def make_rainbow_rgb(colors, width, height):
    """colors is an array of RGB tuples, with values between 0 and 255"""

    img = Image.new("RGBA", (width, height))
    canvas = ImageDraw.Draw(img)

    def hsl(x):
        to_float = lambda x : x / 255.0
        (r, g, b) = map(to_float, x)
        h, s, l = colorsys.rgb_to_hsv(r,g,b)
        h = h if 0 < h else 1 # 0 -> 1
        return h, s, l

    rainbow = sorted(colors, key=hsl)

    dx = width / float(len(colors)) 
    x = 0
    y = height / 2.0
    for rgb in rainbow:
        canvas.line((x, y, x + dx, y), width=height, fill=rgb)
        x += dx
    img.show()
Run Code Online (Sandbox Code Playgroud)

然而,结果看起来并不像一个漂亮的彩虹-y光谱.我怀疑我需要转换为不同的颜色空间或以不同的方式处理HSL三元组.

这看起来不像频谱

有谁知道我需要做些什么来使这些数据看起来像彩虹?

更新:

我正在玩希尔伯特曲线并重新审视这个问题.按照希尔伯特曲线的位置对RGB值(两个图像中的相同颜色)进行排序会产生一个有趣的(如果仍然不完全令人满意)结果:

RGB值沿希尔伯特曲线排序.

Rus*_*ove 11

您正在尝试将三维空间转换为一维空间.正如奥利所说,无法保证你能从中获得令人愉悦的彩虹.

您可以做的是根据饱和度和值/亮度将颜色"桶"成几个不同的类别,然后在类别中进行排序,以获得几个独立的渐变.例如,高饱和度颜色首先用于经典彩虹,然后是中饱和度高值颜色(粉彩),然后是低饱和度(灰度).

另外,如果你关心的是彩虹,转换为HSL,然后踩住饱和度为1.0,值到0.5,转换回RGB和渲染,而不是原来的颜色.


Oli*_*rth 6

想必你按色调(即H)排序?如果SL(或V)是常数,那将会得到一个很好的结果,但如果它们是独立变化的,那么你会得到一点点混乱!