2010-04-05 6 views
4

Je voudrais vérifier quelles sont les couleurs présentes dans une image. Ce sera stocké dans la base de données et utilisé pour un formulaire de recherche. (Rouge = 1, vert = 1, bleu = 0, jaune = 1, noir = 1, blanc = 1, etc.)Obtenir les noms de couleurs utilisés à partir de l'image

img = Magick::Image.read('phosto-file.jpg').first 
img = img.quantize(10 
h = img.color_histogram 
pp h 
{red=12815, green=18494, blue=15439, opacity=0=>13007, 
red=44662, green=47670, blue=51967, opacity=0=>18254, 
red=17608, green=43331, blue=48321, opacity=0=>11597, 
red=21105, green=25865, blue=39467, opacity=0=>10604, 
red=15125, green=36629, blue=22824, opacity=0=>10223, 
red=52102, green=42405, blue=10063, opacity=0=>12928, 
red=39043, green=28726, blue=40855, opacity=0=>7728, 
red=10410, green=8880, blue=7826, opacity=0=>13795, 
red=25484, green=25337, blue=24235, opacity=0=>7351, 
red=44485, green=12617, blue=11169, opacity=0=>14513} 

Comment puis-je convertir les 10 valeurs aux noms de couleur? rouge, vert, NOMATCH, jaune, noir, blanc etc. Seulement besoin du nom de couleur approximatif - pas LimeGreen mais vert etc.

Cordialement. Asbjørn Morell

+0

Le code ruby ​​de votre exemple n'est pas valide: opacity = 0 => 13007 n'est pas valide. – kikito

Répondre

1

Si vous pouviez représenter toutes les couleurs que vous recherchez dans le même format numérique qu'ImageMagick. Ensuite, vous pouvez comparer les valeurs RVB pour trouver à quel point il est le plus proche.

Ainsi, par exemple, si vous avez une valeur d'histogramme (en supposant 255 valeurs pour chaque couleur, YMMV)

{ red => 10, green => 255, blue => 10 } 

Ensuite, vous pouvez le comparer à chacun des

{ 
    red => {red => 255, green => 0, blue => 0}, 
    green => {red => 0, green => 255, blue => 0}, 
    blue => {red => 0, green => 0, blue => 255} 
} 

Donc, si vous ajoutez la différence entre tous les éléments que vous aurez

{ 
    red => 510, 
    green => 20, 
    blue => 510, 
} 

Ainsi, vous pouvez voir clairement que le col ou est le plus proche de vert

MISE À JOUR: Ajout d'une solution dans Ruby


def compare_color(color_val) 
    colors = { 
    :red => [255,0,0], 
    :green => [0,255,0], 
    :blue => [0,0,255] 
    } 

    difference = {} 

    def compare_array(a1,a2) 
    total = 0 
    a1.each_index do |x| 
     total += (a1[x]-a2[x]).abs 
    end 
    total 
    end 

    colors.each do |color,hex| 
    difference[color] = compare_array(color_val,hex) 
    end 

    closest = difference.sort{|a,b| a[1] b[1]}.first                  [closest,difference] 
end 

p compare_color([10,255,10]) 
# [[:green, 20], {:red=>510, :green=>20, :blue=>510}] 
+0

Ce code pourrait être plus facile (d'un point de vue mathématique) d'écrire s'il s'agissait de tableaux plutôt que de hachages, mais cela permet de mieux faire passer le point. – Fotios

+0

Très sympa. Merci pour l'exemple. :) – atmorell

1

La manière la plus simple serait d'avoir une liste de valeurs RVB et les noms correspondants, et vous choisiriez la couleur correspondante la plus proche (dans une certaine marge d'erreur acceptable). Pour les couleurs de base, même une somme très simple de différences dans chacun des canaux RVB peut donner des résultats exploitables, bien que je soupçonne que vous manquerez de noms de couleurs si les données ressemblent à ça. Vous pouvez trouver un list of colour names sur le net, peut-être dépouillant une telle liste pourrait aider. (Notez que ceux-ci attendent généralement une plage de 0..255 pour les couleurs, vous devez donc les convertir à partir de la plage plus large de vos données.)

Une méthode légèrement plus avancée pourrait être de convertir les valeurs RVB dans la teinte, la saturation et la luminance et les utiliser pour générer des noms, par ex. "rouge foncé" lorsque la teinte est rouge, la saturation est suffisamment élevée pour ne pas être grise et la luminance est faible (mais pas assez faible pour être noire).

1

Vous trouverez peut-être this post sur mon blog intéressant. Il explique exactement comment résoudre votre problème. J'ai également publié ColorNamer gem qui vous donne la couleur nommée la plus proche de la valeur RVB ou du hachage HTML. Vous pouvez également utiliser n'importe quel objet Color

Questions connexes