There's no docstring for
get_histogram. What does this function do? What kind of object should I pass for the
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
"""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.
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?)