Je ne suis en aucun cas un expert en couleurs, mais je cherchais désespérément un convertisseur de noms de couleurs RVB/HEX/HSV en python. Après avoir fait quelques recherches, je crois que j'ai fait une solution formidable.Selon IfLoop en this post:
Si vous vous retrouvez à l'aide de la distance cartésienne pour comparer les couleurs, vous devriez normalement traduire les entrées dans un linéaire, l'espace couleur perceptuel, telles que Lab ou YUV. Ni le RGB ni le HSV ne sont linéaires, et la distance cartésienne ne correspond pas vraiment aux deux couleurs similaires. - IfLoop 27 juillet '11 à 21:15
Par conséquent, le code de Jochen Ritzel ne reviendra pas toujours la bonne couleur, comme Graf a souligné. C'est parce que RGB et HSV sont des espaces de couleurs linéaires. Nous devons utiliser un espace de couleurs perceptives linéaire comme YUV.
Donc ce que j'ai fait, c'est que j'ai pris le code de Jochen Ritzel et remplacé le code rgb par du code hsv avec le code rgb to yuv basé sur this post.
colors = dict((
((196, 2, 51), "RED"),
((255, 165, 0), "ORANGE"),
((255, 205, 0), "YELLOW"),
((0, 128, 0), "GREEN"),
((0, 0, 255), "BLUE"),
((127, 0, 255), "VIOLET"),
((0, 0, 0), "BLACK"),
((255, 255, 255), "WHITE"),))
def rgb_to_ycc(r, g, b): #http://bit.ly/1blFUsF
y = .299*r + .587*g + .114*b
cb = 128 -.168736*r -.331364*g + .5*b
cr = 128 +.5*r - .418688*g - .081312*b
return y, cb, cr
def to_ycc(color):
""" converts color tuples to floats and then to yuv """
return rgb_to_ycc(*[x/255.0 for x in color])
def color_dist(c1, c2):
""" returns the squared euklidian distance between two color vectors in yuv space """
return sum((a-b)**2 for a,b in zip(to_ycc(c1),to_ycc(c2)))
def min_color_diff(color_to_match, colors):
""" returns the `(distance, color_name)` with the minimal distance to `colors`"""
return min(# overal best is the best match to any color:
(color_dist(color_to_match, test), colors[test]) # (distance to `test` color, color name)
for test in colors)
if __name__ == "__main__":
r = input('r: ')
g = input('g: ')
b = input('b: ')
color_to_match = (r, g, b)
print min_color_diff(color_to_match, colors)
input('Press enter to exit.')
Maintenant, nous semble finir avec les bonnes couleurs presque à chaque fois:
>>> color_to_match = (2, 2, 0) #Graf's test
>>> print min_color_diff(color_to_match, colors)
>>>
(6.408043991348166e-05, 'BLACK')
Plus exemples:
>>> color_to_match = (131, 26, 26)
>>> print min_color_diff(color_to_match, colors)
>>>
(0.027661314571288835, 'RED')
>>> color_to_match = (69, 203, 136)
>>> print min_color_diff(color_to_match, colors)
>>>
(0.11505647737959283, 'GREEN')
Jusqu'à présent, il semble que ma version semble fonctionner presque parfaitement, mais s'il vous plaît noter: Il est probable que si une couleur RVB est trop clair ou trop sombre, vous obtiendrez probablement retourné «BLANC» ou «NOIR». Pour résoudre ce problème, vous devrez ajouter des couleurs plus claires et plus foncées à votre dictionnaire de couleurs. Ajouter également plus de couleurs comme 'BROWN' et 'GREY' (et ainsi de suite) au dictionnaire de couleurs donnera également de meilleurs résultats.
2,2,0 est pas techniquement noir, tout comme 240.240.240 est pas techniquement gris. – Chris
C'est une approximation. C'est l'objectif de ce script évidemment. –