Comment générer des couleurs "verdâtres" aléatoires

quelqu'un a des suggestions sur la façon de faire randomisés couleurs qui sont tous verdâtre? En ce moment je génère les couleurs par ceci:

color = (randint(100, 200), randint(120, 255), randint(100, 200))

ça marche surtout, mais j'ai beaucoup de couleurs brunâtres.

33
demandé sur Echo 2009-10-19 02:00:37

9 réponses

solution Simple: utilisez le HSL ou HSV colour space au lieu de rgb (convertissez-le ensuite en RGB si vous en avez besoin). La différence est la signification du tuple: où RVB signifie des valeurs pour le rouge, le vert et le bleu, en HSL le H est la couleur (120 degrés ou 0,33 signifiant le vert par exemple) et le S est pour la saturation et le V pour la luminosité. Donc, gardez le H à une valeur fixe (ou pour encore plus de couleurs aléatoires, vous pouvez le randomiser par add / sub un petit nombre aléatoire) et de randomiser le S et le V. voir le wikipedia article.

54
répondu theomega 2009-10-18 22:23:08

comme d'autres l'ont suggéré, la génération de couleurs aléatoires est beaucoup plus facile dans l'espace de couleurs HSV (ou HSL, la différence est assez peu pertinente pour cela)

donc, code pour générer des couleurs aléatoires "green'ish", et (à des fins de démonstration) les afficher comme une série de balises HTML simples et colorées:

#!/usr/bin/env python2.5
"""Random green colour generator, written by dbr, for
/q/how-to-generate-random-greenish-colors-55840/"""

def hsv_to_rgb(h, s, v):
    """Converts HSV value to RGB values
    Hue is in range 0-359 (degrees), value/saturation are in range 0-1 (float)

    Direct implementation of:
    http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_HSV_to_RGB
    """
    h, s, v = [float(x) for x in (h, s, v)]

    hi = (h / 60) % 6
    hi = int(round(hi))

    f = (h / 60) - (h / 60)
    p = v * (1 - s)
    q = v * (1 - f * s)
    t = v * (1 - (1 - f) * s)

    if hi == 0:
        return v, t, p
    elif hi == 1:
        return q, v, p
    elif hi == 2:
        return p, v, t
    elif hi == 3:
        return p, q, v
    elif hi == 4:
        return t, p, v
    elif hi == 5:
        return v, p, q

def test():
    """Check examples on..
    http://en.wikipedia.org/wiki/HSL_and_HSV#Examples
    ..work correctly
    """
    def verify(got, expected):
        if got != expected:
            raise AssertionError("Got %s, expected %s" % (got, expected))

    verify(hsv_to_rgb(0, 1, 1), (1, 0, 0))
    verify(hsv_to_rgb(120, 0.5, 1.0), (0.5, 1, 0.5))
    verify(hsv_to_rgb(240, 1, 0.5), (0, 0, 0.5))

def main():
    """Generate 50 random RGB colours, and create some simple coloured HTML
    span tags to verify them.
    """
    test() # Run simple test suite

    from random import randint, uniform

    for i in range(50):
        # Tweak these values to change colours/variance
        h = randint(90, 140) # Select random green'ish hue from hue wheel
        s = uniform(0.2, 1)
        v = uniform(0.3, 1)

        r, g, b = hsv_to_rgb(h, s, v)

        # Convert to 0-1 range for HTML output
        r, g, b = [x*255 for x in (r, g, b)]

        print "<span style='background:rgb(%i, %i, %i)'>&nbsp;&nbsp;</span>" % (r, g, b)

if __name__ == '__main__':
    main()

la sortie (lorsqu'elle est visualisée dans un navigateur web) doit ressembler à quelque chose du genre:

Example output, showing random green colours

Edit : Je ne savais pas pour le module colorsys. Au lieu de la fonction hsv_to_rgb ci-dessus, vous pouvez utiliser colorsys.hsv_to_rgb , ce qui rend le code beaucoup plus court (ce n'est pas tout à fait un remplacement Direct, Car ma fonction hsv_to_rgb s'attend à ce que la teinte soit en degrés au lieu de 0-1):

#!/usr/bin/env python2.5
from colorsys import hsv_to_rgb
from random import randint, uniform

for x in range(50):
    h = uniform(0.25, 0.38) # Select random green'ish hue from hue wheel
    s = uniform(0.2, 1)
    v = uniform(0.3, 1)

    r, g, b = hsv_to_rgb(h, s, v)

    # Convert to 0-1 range for HTML output
    r, g, b = [x*255 for x in (r, g, b)]

    print "<span style='background:rgb(%i, %i, %i)'>&nbsp;&nbsp;</span>" % (r, g, b)
21
répondu dbr 2013-08-24 04:59:39

vérifiez le module colorsys :

http://docs.python.org/library/colorsys.html

utilisez l'espace de couleur HSL ou HSV. Randomiser la teinte pour être proche du vert, puis choisir tout à fait au hasard substance pour la saturation et V (luminosité).

16
répondu Anthony Mills 2009-10-18 22:09:00

si vous vous en tenez à RGB, vous devez simplement vous assurer que la valeur G est supérieure à la valeur R et B, et essayer de garder les valeurs bleues et rouges similaires pour que la teinte ne devienne pas trop folle. S'étendant à partir de Slaks, peut-être quelque chose comme (je ne sais rien de Python):

greenval = randint(100, 255)
redval = randint(20,(greenval - 60))
blueval = randint((redval - 20), (redval + 20))
color = (redval, greenval, blueval)
9
répondu Matt Bayliss 2009-10-18 23:13:10

donc dans ce cas vous êtes assez chanceux pour vouloir des variations sur une couleur primaire, mais pour des usages artistiques comme celui-ci, il est préférable de spécifier des coordonnées de roue de couleur plutôt que des grandeurs de couleur primaire.

vous voulez probablement quelque chose du module colorsys comme:

colorsys.hsv_to_rgb(h, s, v)
    Convert the color from HSV coordinates to RGB coordinates.
5
répondu DigitalRoss 2009-10-18 22:09:31

la solution avec l'espace de couleur HSx est une très bonne. Cependant, si vous avez besoin de quelque chose d'extrêmement simpliste et n'avez pas d'exigences spécifiques concernant la distribution des couleurs (comme l'uniformité), une solution simpliste basée sur le RVB serait juste pour s'assurer que la valeur G est plus grande que les deux R et b

rr = randint(100, 200)
rb = randint(100, 200)
rg = randint(max(rr, rb) + 1, 255)

cela vous donnera des couleurs "verdâtres". Certains seront un peu verdâtres. Vous pouvez augmenter le degré de verdeur garanti par augmentation (absolue ou relative) de la limite inférieure du dernier appel randint .

3
répondu AnT 2009-10-18 23:46:23

ce que vous voulez est de travailler en termes de HSL au lieu de RGB. Vous pouvez trouver une gamme de teinte qui répond "verdâtre" et choisir aléatoirement teinte. Vous pouvez également choisir la saturation aléatoire et la légèreté, mais vous voudrez probablement garder votre saturation près de 1 et votre légèreté autour de 0,5, mais vous pouvez jouer avec eux.

ci-dessous est un code actionscript pour convertir HSL en RGB. Je n'ai pas touché à python depuis un moment ou il posterait le python version.

je trouve que greenish est quelque chose comme 0.47*PI à 0.8*PI.

    /**
@param h hue [0, 2PI]
@param s saturation [0,1]
@param l lightness [0,1]
@return object {r,g,b} {[0,1],[0,1][0,1]}
*/
public function hslToRGB(h:Number, s:Number, l:Number):Color
{
    var q:Number = (l<0.5)?l*(1+s):l+s-l*s;
    var p:Number = 2*l-q;
    var h_k:Number = h/(Math.PI*2);
    var t_r:Number = h_k+1/3;
    var t_g:Number = h_k;
    var t_b:Number = h_k-1/3;
    if (t_r < 0) ++t_r; else if (t_r > 1) --t_r;
    if (t_g < 0) ++t_g; else if (t_g > 1) --t_g;
    if (t_b < 0) ++t_b; else if (t_b > 1) --t_b;
    var c:Color = new Color();
    if (t_r < 1/6) c.r = p+((q-p)*6*t_r);
    else if (t_r < 1/2) c.r = q;
    else if (t_r < 2/3) c.r = p+((q-p)*6*(2/3-t_r));
    else c.r = p;
    if (t_g < 1/6) c.g = p+((q-p)*6*t_g);
    else if (t_g < 1/2) c.g = q;
    else if (t_g < 2/3) c.g = p+((q-p)*6*(2/3-t_g));
    else c.g = p;
    if (t_b < 1/6) c.b = p+((q-p)*6*t_b);
    else if (t_b < 1/2) c.b = q;
    else if (t_b < 2/3) c.b = p+((q-p)*6*(2/3-t_b));
    else c.b = p;
    return c;
}
1
répondu putgeminmouth 2009-10-18 22:27:17

la façon la plus simple de faire cela est de s'assurer que les composants Rouge et bleu sont les mêmes, comme ceci: (pardonnez mon Python)

rb = randint(100, 200)
color = (rb, randint(120, 255), rb)
0
répondu SLaks 2009-10-18 22:19:17

je dirais avec L'approche HSV tout le monde mentionné. Une autre approche serait d'obtenir une belle photo haute résolution qui un peu de verdure en elle, recadrer les parties non-vertes, et de choisir au hasard des pixels de celui-ci en utilisant PIL .

0
répondu Dickon Reed 2009-10-19 20:19:33