5

Status: I am developing my own library


Question:

Is there any library that can do color classification?

I imagine the workflow like this:

>>> import colorclassification
>>> classifier = colorclassification.Classifier
>>> color = classifier.classify_rgb([255, 255, 0])
['yellow']
>>> color = classifier.classify_rgb([255, 170, 0])
['orange']

The library must not necessarily be for python. Any language where I can view the source code of the module/library will do fine.

Community
  • 1
  • 1
joar
  • 15,077
  • 1
  • 29
  • 54
  • 1
    I tagged this Python based on your example code. Please tag with a language/platform in the future so people can actually give relevant answers. `[colors]` by itself could apply to a *vast* number of languages and is not at all specific enough to establish the context of your question. – eldarerathis Jul 27 '11 at 15:28
  • I don't care for python. As it is now I can't find anything at all, if I get a link to any library that can do it, it will be valuable. – joar Jul 27 '11 at 15:32

1 Answers1

11

One way you could do this is just by finding the "closest" color. suppose we have a collection of colors, It doesn't have to cover all 16777216 possible rgb values, it doesn't even need to be in rgb, but for the sake of simplicity, it might look something like so:

colors = {'red': (255,0,0),
          'green': (0,255,0),
          'blue': (0,0,255),
          'yellow': (255,255,0),
          'orange': (255,127,0),
          'white': (255,255,255),
          'black': (0,0,0),
          'gray': (127,127,127),
          'pink': (255,127,127),
          'purple': (127,0,255),}

Lets define a mechanism that tells us what we really mean by "closest" color. In this case, i'll use a simple cartesian distance, but anything that can compare two colors for how similar they are will do.

def distance(left, right):
    return sum((l-r)**2 for l, r in zip(left, right))**0.5

class NearestColorKey(object):
    def __init__(self, goal):
        self.goal = goal
    def __call__(self, item):
        return distance(self.goal, item[1])

And that's actually all we need. We can use the builtin min() (or max if your similarity function returns higher values for more similar colors)

>>> min(colors.items(), key=NearestColorKey((10,10,100)))
('black', (0, 0, 0))
>>> min(colors.items(), key=NearestColorKey((10,10,200)))
('blue', (0, 0, 255))
>>> min(colors.items(), key=NearestColorKey((100,10,200)))
('purple', (127, 0, 255))
>>> 
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • 7
    If you end up using Cartesian distance to compare colors, you should normally translate the inputs into a *linear, perceptual* color space, such as Lab or Yuv. Neither RGB nor HSV are linear, and so cartesian distance doesn't much relate to similar two colors really are. – SingleNegationElimination Jul 27 '11 at 21:15
  • Thank you for this post, this is by far the most relevant. However, I just finished with [my library](https://github.com/jwandborg/py-color-classifier). It is a whole different approach, more condition-based not so much magic, that can be either good or bad, but I'll definitively settle for you solution, since it's simpler than my current, and I'm a bit tired of defining color ranges. – joar Jul 27 '11 at 21:54
  • I'm done with [my implementation](https://github.com/jwandborg/py-colorclassifier/blob/v2.0/colorclassifier.py), it works perfectly :) – joar Jul 27 '11 at 23:59
  • 1
    @joar it says 404 as address of your work, please move it at 201 – TheExorcist Feb 18 '22 at 10:46