detect the most used colour in an image using python
I want to find the most used colour in an image using python. for example detect the colour of the object in the following image
http://www.shopcrazy.com.ph/wp-content/images/2007/02/shiny-bags-01.jpg.
how to detect the base colour from the RGB codes(example -开发者_运维技巧 red in the above image).
Since you will most likely not want a histogram of all the million colors that are possible using a 24-bit color space, I suggest transforming the image into HSV space instead. Then you can partition the Hue part of that space into a number of bins that describe the hues you want to find ("dark red", "orange red", or whatever). Then make a histogram of these bins and find which is the dominant hue, which is the "color".
The wikipedia article http://en.wikipedia.org/wiki/HSL_and_HSV should get you started. IF you are using an image processing library chances are that a rgb-to-hsv/hsl function exists.
Also, if the images are large and speed is an issue, you might consider downsampling the image to a smaller size before histogramming.
The brute force approach is to loop over all pixels in the image and keep count of R, G, B values. A more refined approach is to use Python Image Library histogram function and calculate the average of all colors.
I would use the Python Image Library. This is a piece of code that computes the number of white pixels/non-white pixels in an image.
import sys
from PIL import Image
im = Image.open(sys.argv[1])
white = 0
black = 0
for i in im.getdata():
if i == (255,255,255):
white += 1
else:
# we assume black everything that is not white:
black += 1
print im.size[0],im.size[1],white,black
In your case, I would do a dictionary to keep every rgb triple against a counter, so I would rework the program like this (not tested)
import sys
from PIL import Image
im = Image.open(sys.argv[1])
count= {}
for i in im.getdata():
if not count.has_key(i):
count[i] = 0
count[i] += 1
You can now check the one with the highest count and get the most used rgb triple. Of course, if you want to check also vicinal colors, you will have to convert to HSV and check the distances between different HSV points, then decide which distance is too much. Points sufficiently near in HSV space (and in particular the hue component) are most likely the same color and consequently can be summed together.
If you are really sure that you will always have only one dominant color (no bags in two colors, e.g.), then a crude histogram on the H&S dimensions of HSV should suffice.
Otherwise, you can (and should ) use mean shift. It's fairly simple, does exactly what you want, and there are libraries you can use, although I could not find anything in Python. You can either implement it, or call C++ code.
The basic idea of the algorithm is this: each pixel looks at nearby pixels of similar color, and changes its color to the weighted mean of all their colors; rinse and repeat. Pretty soon you have all the colors in the image clustered very tightly around a few predominant colors.
As suggested, it will be handier to convert your image from RGB to HSV. The standard library module colorsys contains the function rgb_to_hsv
to that effect. Then, you can map colors on an image, say with H as x and S as y. Select points in that space, and give them names; the more points, the better. Then, for every pixel in your image, find the closest of the points you selected and use its name as the pixel value. Count which name occurs most times.
Do you want me to supply code?
Sort the pixels in-place, then loop through the image and find the longest run.
精彩评论