3

I am processing an image pixel by pixel and I need to get name of the color for each pixel. I have these main color names: yellow, magenta, cyan, red, green, blue, white, black. I also have RGB and CMYK numbers of each pixel. How would I approximate the color of the pixel to one of the above based on those numbers? It does not need to be precise, just a very general approximation. Is there any maths that I can do with RGB or CMYK to determine that? I would rather prefer a simple solution than a precise one.

Army
  • 105
  • 1
  • 8
  • You're asking how to tell whether a color is mainly **yellow** given the **cyan**, **magenta**, **yellow** and **black** components of the color? Have you at least tried to do this? – beaker Nov 30 '19 at 17:08
  • Well, for example i have a pixel with RGB(70,200,220). How do i determine whether it is considered yellow or magenta or cyan, etc.. – Army Nov 30 '19 at 17:18
  • What are the CMYK values for that color? – beaker Nov 30 '19 at 17:20
  • it would be (68%, 9%, 0%, 14%) for this particular one – Army Nov 30 '19 at 17:23
  • So what color do you think that is? – beaker Nov 30 '19 at 17:25
  • Well, this one is pretty obviously cyan to the eye, and I do not doubt my eyes. The thing is that I need to programmatically determine that. Use some kind of calculations and output the name of the color having just the RGB (That i can also convert to CMYK if that helps) – Army Nov 30 '19 at 17:29
  • If you were a little bit more forthcoming about what you are trying to do, I suspect you might get a better answer. Let's say your image is a fairly smallish (by modern standards) 1080p image at 1920x1080 pixels. What are you going to do with a list of 2.073 million approximate colour names? – Mark Setchell Nov 30 '19 at 17:40
  • I need to find the percentages of the colors that this image has. I need an output like this: _this image is 23% white, 11% yellow_, etc... – Army Nov 30 '19 at 17:46
  • 1
    I can't tell if you're looking at an image of the color or the CMYK values. So let me suggest this: if you take the CMYK values and convert the maximum value to 1 and the minimum value to 0. Then, for the other two colors, assign them 1 or 0 based on whether their value is closer to the max or the min. Now you have a table of 16 possible values that you should be able to map to your 8 colors. – beaker Nov 30 '19 at 17:47
  • Great idea, combining that and another solution to discover blacks and whites more reliably seems to do the work @beaker – Army Nov 30 '19 at 22:09

2 Answers2

2

Let's take this as a starting image:

enter image description here

Now, make a map of all the colours that we want to look for, bearing in mind that ImageMagick uses X11 colornames where green is named lime:

magick xc:black xc:white xc:red xc:lime xc:blue xc:cyan xc:magenta xc:yellow +append map.png

That makes this - which I have magnified because it is only 8 pixels wide and 1 pixel tall:

enter image description here

Now, we just ask imageMagick to map all the pixels in the original image to whatever colour is nearest in the colours in our map:

magick artistic-swirl.jpg +dither -remap map.png result.png

enter image description here

Now we look at the distribution of pixels in the colormap of the result:

magick identify -verbose result.png | grep -A9 Histogram

Output

 Histogram:
      5063: (0,0,0) #000000 black
     40831: (0,0,255) #0000FF blue
      2831: (0,255,0) #00FF00 lime
     44027: (0,255,255) #00FFFF cyan
     61648: (255,0,0) #FF0000 red
     29828: (255,0,255) #FF00FF magenta
     38729: (255,255,0) #FFFF00 yellow
     27043: (255,255,255) #FFFFFF white

And we can see there are 5063 pixels that are black, and 40831 pixels that are blue... and so on.

Note that you can do all this with wand which is a Python binding to ImageMagick.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Pastel colors are all mapped to white, but a person would call pastel green as green, not white. “Nearest” in RGB space is definitely not how humans classify colors. Still, I don’t have a better solution… :D – Cris Luengo Jun 30 '22 at 14:20
  • @CrisLuengo It was clearer before when I used Paddington bear as the image, but apparently I can't use that image any more... ‍♂️ You can see the edit history. – Mark Setchell Jun 30 '22 at 15:10
  • Were you asked to remove that picture? Wow! Crazy! – Cris Luengo Jun 30 '22 at 16:03
0

While the other solution posted will work for KNOWN names, take a look at models and papers like this one to actually generalize and understand how to translate (even) unknown colors to useful names.

Edit: Even though this isn't what OP wanted, I ended up spending a couple of hours to wire it all up to work easily within Docker/VSCode. See here for a way to quickly get up and running with this repository.

I hope this helps someone!

Ani
  • 10,826
  • 3
  • 27
  • 46
  • Not what I needed at the moment, but a very interesting solution nevertheless! Will take a look – Army Nov 30 '19 at 22:13