Use color names from image

I would like to check what colors are present in the image. This will be stored in the database and used for the search form. (red = 1, green = 1, blue = 0, yellow = 1, black = 1, white = 1, etc.)

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} 

How do I convert 10 values ​​to color names? red, green, NOMATCH, yellow, black, white, etc. All you need is a crude color name - not LimeGreen, but green, etc.

Sincerely. Asbjorn Morell

+4
source share
3 answers

If you can represent all the colors you are looking for in the same number format that ImageMagick returns. You can then compare the RGB values ​​to find what it is closest to.

So, for example, if you have a histogram value (assuming 255 values ​​for each color, YMMV)

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

Then you can compare it with each of

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

So, if you add the difference between all the elements you get

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

So you can clearly see that the color is close to green

UPDATE: added solution in 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}] 
+1
source

A simple way would be to have a list of RGB values ​​and their corresponding names, and you would choose the closest matching color (within the margin of error). For basic colors, even a very simple sum of the differences in each of the RGB channels can give workable results, although I suspect that you will run out of the color name if the data looks like this. You can find a list of color names on the net, perhaps this will help to remove one such list. (Note that they usually expect a range of 0..255 for colors, so you will need to convert the data from a wider range to your data.)

Converting RGB values ​​to hue, saturation and brightness and using them to generate names, for example, may be a slightly more complicated way. β€œdark red” when the hue is red, the saturation is high enough not to be gray, and the brightness is low (but not low enough to be black).

+1
source

You may find this blog post interesting. It accurately explains how to solve your problem. I also released ColorNamer gem , which gives you the closest named color from an RGB value or an HTML hash. You can also use any Color object.

+1
source

Source: https://habr.com/ru/post/1306015/


All Articles