Python 如何生成接近rgb值的颜色?

Python 如何生成接近rgb值的颜色?,python,colors,Python,Colors,我希望能够生成多个接近一个RGB颜色的颜色,如下图所示 以下是我使用Python所做的工作: def similarColors(rgb, loop=6): difference = 30 colors = [] for i in range(loop): red = rgb[0] red_highest = red + difference red_lowest = red - difference re

我希望能够生成多个接近一个RGB颜色的颜色,如下图所示

以下是我使用Python所做的工作:

def similarColors(rgb, loop=6):
    difference = 30
    colors = []
    for i in range(loop):
        red = rgb[0]
        red_highest = red + difference
        red_lowest = red - difference
        red = randint(red_lowest, red_highest)

        green = rgb[1]
        green_highest = green + difference
        green_lowest = green - difference
        green = randint(green_lowest, green_highest)

        blue = rgb[2]
        blue_highest = blue + difference
        blue_lowest = blue - difference
        blue = randint(blue_lowest, blue_highest)

        colors.append([red, green, blue])
    return colors

palette = similarColors([244, 83, 28])
问题:我觉得我用这种方法把事情复杂化了。有没有办法让上面的代码更简洁


我希望避免对每种颜色(红色、蓝色、绿色)分别进行相同的处理,我也不确定这种方法是否真的精确到我想要达到的效果。

无需复制粘贴每种颜色,您可以使用如下for循环:

def similarColors(rgb, loop=6, difference=30):
    colors = []
    for _ in range(loop):
        color = []
        for curr_color in rgb:
            color.append(randint(curr_color - difference, curr_color + difference))
        colors.append(color)

    return colors
请注意,我还在参数中添加了
difference


还有一个错误,rgb部分可以是<0或>255,你可以通过使用
max(0,min(255,randint(curr\u color-difference,curr\u color+difference))
来解决这个问题。

我们可以通过循环rgb组件来压缩代码。然而,您当前的算法中有一个bug:它可以生成<0或>255的颜色通道值,因此我们需要修复它

from random import randint

def similarColors(rgb, loop=6):
    colors = []
    delta = 30
    for i in range(loop):
        new_rgb = [randint(max(0, x - delta), min(x + delta, 255)) for x in rgb]  
        colors.append(new_rgb)                
    return colors

colors = similarColors([244, 83, 28])
print(colors)
典型输出

[[249, 75, 28], [226, 111, 34], [235, 85, 46], [228, 66, 28], [244, 62, 8], [233, 102, 21]]
[[236, 84, 65], [233, 74, 78], [226, 93, 73], [249, 88, 89], [240, 84, 40], [226, 75, 22]]

你说:“我也不确定这个方法是否真的精确到我想要达到的目标。”。我不知道你到底想实现什么,但我能看到的一个问题是人类视觉系统对R、G和B的敏感度不一样。因此,一个通道中给定量的变化不会产生与另一个通道中相同变化相同的效果。为了正确地处理这个问题,你需要在一个与人类视觉系统更紧密一致的色彩空间中工作,例如。然而,我们可以通过使用通道三角洲上的比例因子得到合理的近似值

Wikipedia上的文章提供了一个公式,可用于计算RGB颜色的亮度:

y = 0.299*R + 0.587*G + 0.114*B
该公式已用于模拟NTSC和PAL电视

下面是使用这些比例因子的上述代码的一个版本。我们用这些比例因子除以我们的基准delta,蓝色的delta最大,绿色的delta最小,因为眼睛对绿色最敏感,对蓝色最不敏感

def similarColors(rgb, loop=6):
    colors = []
    delta = 10
    deltas = [round(delta / u) for u in (0.299, 0.587, 0.114)]
    for i in range(loop):
        new_rgb = [randint(max(0, x - delta), min(x + delta, 255)) 
            for x, delta in zip(rgb, deltas)]
        colors.append(new_rgb)
    return colors

colors = similarColors([244, 83, 28])
print(colors)
典型输出

[[249, 75, 28], [226, 111, 34], [235, 85, 46], [228, 66, 28], [244, 62, 8], [233, 102, 21]]
[[236, 84, 65], [233, 74, 78], [226, 93, 73], [249, 88, 89], [240, 84, 40], [226, 75, 22]]

为了提高代码的效率,由于我们使用的是固定基数
delta
,我们可以预先计算
delta
数组,而不是每次调用
similarColors
时都重新计算它,如果您可以使用
numpy
,那么更紧凑的解决方案是这样的:

import numpy as np

def similarColors(rgb, loop=6):
    delta = 30
    origClrs = np.tile(np.array(rgb), (loop, 1))
    randOffsets = np.random.randint(-delta, delta, size=(loop, 3))
    return origClrs + randomOffsets

现在把它放在适当的位置,我想说这更容易-没有返回值,并且将它应用到图片的每个像素上会自动改变图像的颜色picture@Sanitiy每个Python函数都会返回一些内容:
None
,如果没有显式返回对象,则返回该函数。当然,函数可以接受一个列表参数,我们可以用新的颜色列表来扩展它。这比扩展一个全局的
colors
列表要好。我不知道你所说的“将此应用于图片的每个像素”到底是什么意思,因为
similarColor
将单个颜色值作为其参数并返回6个颜色值。就精度而言,我的意思是,如果颜色是橙色,它将显示橙色的阴影,而不是其他颜色。@Lindow啊,好的。新版本在这方面稍好一些。但如果我们在HSV或HLS颜色空间中工作,我们可以做得更好。通过使色调增量变小,新颜色将具有与原始颜色相似的色调。看看这个模块,它有你需要的转换功能,试着编码一些东西,如果你卡住了,问一个新问题。我在我的答案中添加了一个新的版本,它(部分)补偿了人类视觉系统对红色、绿色和蓝色不同样敏感的事实。