Occurrence of list in ndarray

Viewed 224

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,
}
3 Answers

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})

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}

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])
Related