How to Get an Image’s Primary Colors

Many photo sites allow you to search images by their primary colors, at first glance it looks like magic to me, but I don’t believe in magic, so I gave it a second thought and quickly found out that it is quite simple.

The HSV color model describes color (hue) in terms of  their shades and their brightness (to read more about how to convert RGB to HSV see this wikipedia link). We can ignore the shades and the brightness and use only the hue. The hue is a number between 0 to 359 and can be represented by a color circle. By looking at this circle, you can easily divide it into color segments, I found 17 colors.

RGB_color_circle
Color circle – (wikimedia)

This theory can be easy transformed into a code, first let’s start by converting the image from RGB to HSV, I used the OpenCV library to do that. Then I ignored the S and V, put hue buffer in a histogram by using the numpy library, and then I looped through it using a color range array and created a dictionary of  color names and appearances, after that I simply sorted it.

The following python code returns the image’s 3 most dominent colors:

import  numpy   np
import  cv2

def getPrimaryColor(img):

    Hue_color_name =[
    [355,360, "Red"],
    [346,355, "Pink-Red"],
    [331,345,"Pink"],
    [321,330,"Magenta-Pink"],
    [281,320,"Magenta"],
    [241,280,"Blue-Magenta"],
    [221,240,"Blue"],
    [201,220,"Cyan-Blue"],
    [170,200,"Cyan"],
    [141,169,"Green-Cyan"],
    [81,140,"Green"],
    [61,80,"Yellow-Green"],
    [51,60,"Yellow"],
    [41,50,"Orange-Yellow"],
    [21,40,"Orange-Brown"],
    [11,20,"Red-Orange"],
    [1,10, "Red"]
    ]

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    hue , s , v  = cv2.split(hsv)
    hue_hist , bins = np.histogram(hue, 360)
    hues =defaultdict()
    i=0
    while i<len(Hue_color_name):
      if Hue_color_name[i][2] in hues:
        hues[Hue_color_name[i][2]]=hues.get(Hue_color_name[i][2])+np.sum(hue_hist[Hue_color_name[i][0]:Hue_color_name[i][1]])
      else:
        hues[Hue_color_name[i][2]]=(np.sum(hue_hist[Hue_color_name[i][0]:Hue_color_name[i][1]]))
      i+=1

    s_hues = sorted(hues, key=hues.get, reverse=True)

    return s_hues[0] , s_hues[1] , s_hues[2]
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s