2

I have an RGB image -ndarray- and I want to count the occurrence of some colors like [255,0,0] or [0,0,255] in this image.

example of image data

np.ones((3, 3, 3)) * 255

array([[[255., 255., 255.],
        [255., 255., 255.],
        [255., 255., 255.]],
       [[255., 255., 255.],
        [255., 255., 255.],
        [255., 255., 255.]],
       [[255., 255., 255.],
        [255., 255., 255.],
        [255., 255., 255.]]])

So as result I want something like this

{
'[255,255,255]' : 9,
}
2
  • I added an example. so in general the dimension of RGB image is (width, height, 3) Commented Jul 3, 2019 at 8:43
  • 1
    np.unique can be used in the linked dupe @MatteoPeluso being a 1d array. However with a 2darray its a little more tricky :) Commented Jul 3, 2019 at 9:36

3 Answers 3

4

One solution could be the Counter function:

from collections import Counter
import numpy as np

# Generate some data
data = np.ones((10, 20, 3)) * 255

# Convert to tuple list
data_tuple = [ tuple(x) for x in data.reshape(-1,3)]
Counter(data_tuple)

Returns:

Counter({(255.0, 255.0, 255.0): 200})
Sign up to request clarification or add additional context in comments.

1 Comment

thank you for your answer. It works very well but it takes long time
3

Whereas its possible to use Counter or opencv histogram function to compute frequency of every single pixel , for specific pixels, its more efficient to use this:

import numpy as np

ar = np.ones([3,3,3]) *255
ar[1,1,:] = [0, 0, 200]

pixels = dict()
pixels['[255, 255, 255]'] =  np.sum(np.all(ar == [255,255, 255], axis = 2))
pixels['[0, 0, 200]'] =  np.sum(np.all(ar == [0, 0, 200], axis = 2)) 

result : {'[255, 255, 255]': 8, '[0, 0, 200]': 1}

Comments

1

Here's an approach using NumPy. Being values in the range 0-255, we could view the rows as tuples with three elements of type f8, and use np.unique to count the occurrences of the actual rows in the original ndarray. Using nakor's array:

a = np.ones((10, 20, 3)) * 255

We could then do:

vals, counts = np.unique(a.view('f8,f8,f8'), return_counts=True)

Where:

print(vals)
array([(255., 255., 255.)],
      dtype=[('f0', '<f8'), ('f1', '<f8'), ('f2', '<f8')])

print(counts)
array([200])

1 Comment

I tried with a real picture and I had this error ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.