1

I want to be able to count the number of colors in a part of an image.

One way I thought about doing is plotting a histogram for the greyscale image and then counting the number of peaks, and that's the number of colors.


histogram, bin_edges = np.histogram(gray_image, bins = 256, range=(0,1))
plt.plot(histogram)
peaks = signal.find_peaks_cwt(histogram, 10)

When i do it this way, the signal.find_peaks_cwt says there too many indices for array.

How do I go about this or is there a better way to count the number of colors?

  • What do you mean by number of colors? Is it unique colors? For example, if I have a checkboard image with only black and white. In this case, number of colors would be 2? – fabda01 Jul 20 '20 at 02:42
  • Yes, i guess unique colors. Or colors that are not like the others – stickersiskool Jul 20 '20 at 02:46
  • I am analyzing moles. The majority of a mole is brown, but sometimes there can be green or blue or red color in the mole. I'm trying to count where the colors aren't the same – stickersiskool Jul 20 '20 at 02:46
  • Do you need to do any clustering? is the color (255, 128, 0) different from the color (255, 127, 0), or the same? – Juan Jul 20 '20 at 02:57
  • probably clustering. I don't need each shade exactly, but a count that the color has changed. – stickersiskool Jul 20 '20 at 03:01
  • Maybe you could add a couple of images and say what the expected answer is to clarify? – Mark Setchell Jul 29 '20 at 08:20

1 Answers1

1

This answer got a little to long for a comment:

It is not quite clear to me what you are trying to do. Do you want to count all distinguishable elements in an image, or do you want to count all shades of e.g. red as one color?

Also images can be represented using different kind of datatypes (eg. float ∈ [-1, 1] or uint8 ∈ [0, 255]). In your first line you apparently expect to have an image of type float according to range=(0,1). With binning you might loose the information about distinguishable elements and therefore not be able to count the number of distinguishable elements.

Counting distinguishable colors

For counting all available colors (= distinguishable elements) in a gray scale image you can use the following one-liner. (This will of course also work for float images. If you really want to distinguish between every color this is perfect, but if not your command np.histogram is a good idea.)

len(set(gray_image.flatten()))

As for the error you got with scipy.signal.find_peaks_cwt(histogram, 10), find_peaks_cwt() expects a 1D array as second argument. If you provide a numpy array it will work just fine.

Counting clusters of similar colors

In case you want to cluster similar colors and not count them twice, there are different approaches you can choose. The keyword here is "color quantization". As shown in this post you can use clustering algorithms to quantize the colors used in the image. After color quantization you can simply reshape the image to preserve the RGB tuples and use numpys unique method like that:

import numpy as np

len(np.unique(color_image.reshape(-1, 3), axis = 0))

There are a lot of methods to reduce the number of colors. Pillow has two functions for that posterize and quantize. a method with k-means using Scikit learn was shown in the post i mentioned earlier and also you could try to use a distance metric when using a predefined set of colors.

Night Train
  • 2,383
  • 3
  • 18
  • 35