1

I have an np.array which is essentially an image in RGB format. I reshaped it to be more easy to work with. So, its shape is something like: (22618, 3) with each row corresponding to a pixel. I want to check if there are some pixels that correspond to a specific color(s) and also how many of them are of this color(s).

Let's say colors are (0, 255, 255) and (255, 0, 0) defined in a tuple. Also the np.array that contains the data is data (truly original!).

When I try:

any(data[(data2 == colors[0])])

it works as expected. If there are any pixels (triplets) corresponding to triplet of colors[0] it returns True otherwise False. But when I try something like:

np.sum(data[(data == colors[1])])

the result is summing up all pixel values (R+G+B) of each pixel found to contain the same color.

I used just the array containing the boolean values (data == colors[1]) with little success. Also, I tried summing to a specific axis does not help that much:

np.sum(data == colors[1], axis=0)

array([ 373, 22618, 22618])

I could do some tricky maths here knowing that at most 373 pixels could be of the correct color but it's not precise calculation. I could use some functionality like bincount in this question but the results seem to need extra work and also some experiments did not show to work as expected.

So, how do I count the number of pixels that have the same color? Any ideas?

Eypros
  • 5,370
  • 6
  • 42
  • 75

3 Answers3

3

You want all elements of a given row to match your template color, so you should use np.all row-wise, that is along axis 1. This will result in a boolean array with one truth value for each row.

All that's left to do is count them:

np.count_nonzero(np.all(data == colors[i], axis=1))
Jonas Adler
  • 10,365
  • 5
  • 46
  • 73
Paul Panzer
  • 51,835
  • 3
  • 54
  • 99
0

Let's take this data:

data = np.array([(0,0,255),(0,0,255),(0,255,0),(0,0,0)])

and we're looking for this colour:

colour = (0,0,255)

Count how many tuples are matching:

match = [(x == colour).all() for x in data]

Your answer:

print(np.sum(match))

One-liner:

print(np.sum([(x == colour).all() for x in data]))

(If I got your question right)

Lukasz Tracewski
  • 10,794
  • 3
  • 34
  • 53
0

If you are interested in many colors, it would be more efficient to do something along these lines:

import numpy_indexed as npi
unique_colors, counts = npi.count(npi.intersection(data, colors))

This will efficiently compute the counts for all colors of interest. (Disclaimer: I am the author of the numpy_indexed package).

Eelco Hoogendoorn
  • 10,459
  • 1
  • 44
  • 42