There's no docstring for get_histogram
. What does this function do? What kind of object should I pass for the img
argument?
You import skimage.io.imread
and PIL.Image
but you don't use either of them.
This comment doesn't seem relevant:
#histogram = plt.hist(img.flatten(), bins=100, facecolor='green', alpha=0.75)
There are two useless print
statements. I presume that these are left over from a debugging session and you forgot to remove them. You might find it useful to learn to use the Python debugger which would avoid the need to add print
statements to the code.
There are two pieces of functionality here: (i) extracting the colour data from an image into a Numpy array; (ii) converting colour data from RGB to the Lab colour space. It would make sense to split these up (especially as piece (ii) is so simple).
The function is poorly named: it does not actually get a histogram. (Because you discard the colour counts in the num
array.) This makes me wonder what you are using this function for.
You use the spelling "colour" but the APIs you are calling use the spelling "color". Even if you prefer the "colour" spelling, it's better to be consistent. That way there's less chance of forgetting and making a mistake.
Creating a Numpy array from an a Python list is usually straightforward if you pass the list to the numpy.array
function. There's no need to mess about with numpy.zeros
and assigning column-wise.
So I'd write the following:
import numpy as np
def distinct_colors(img):
"""Return the distinct colors found in img.
img must be an Image object (from the Python Imaging Library).
The result is a Numpy array with three columns containing the
red, green and blue values for each distinct color.
"""
width, height = img.size
colors = [rgb for _, rgb in img.getcolors(width * height)]
return np.array(colors, dtype=np.uint8)
The conversion to Lab colour space is so simple that I don't think it needs a function.
Update
There's one minor difficulty: the skimage.color
functions all demand an array with 3 or 4 dimensions, and so only support 2- and 3- dimensional images. Your array of distinct colours is a 1-dimensional image, so it's rejected. But you can easily use numpy.reshape
to turn it into a 2-dimensional image whose first dimension is 1 before passing it to rgb2lab
, like this:
colors = distinct_colors(img)
rgb2lab(colors.reshape((1, -1, 3)))
Or if you prefer the second dimension to be 1, use .reshape((-1, 1, 3))
.
(Personally I think the skimage.color
behaviour is absurd. Why does it care about the number of dimensions? There doesn't seem to be any obvious reason in the code. Maybe it would be worth filing a bug report?)