Counting unique pixel value of an image

Question:

I would like to count the number of unique pixel values and filter out those number more than a threshold and save it in a dict.

# Assume an image is read as a numpy array
np.random.seed(seed=777)
s = np.random.randint(low=0, high = 255, size=(100, 100, 3))
print(s)

This is how I count the number of unique values(1*3 array).

np.unique(img.reshape(-1, 3), axis=0, return_counts=True)

How can I add some logic to filter out and turn it to a dict?

Asked By: user16971617

||

Answers:

You can use Counter from collections module instead of using return_counts=True:

from collections import Counter

thresh = 2

counts = {pix: val for pix, val in Counter(map(tuple, np.unique(img.reshape(-1, 3), axis=0))).items()
                   if val > thresh}
Answered By: Corralien

You can use:

np.random.seed(seed=1606)
img = np.random.randint(low=0, high = 255, size=(100, 100, 3))

# set upi threshold
thresh = 2

# count unique values and set up mask
vals, counts = np.unique(img.reshape(-1, 3), axis=0, return_counts=True)
mask = counts>thresh

# form a dictionary of values/counts > threshold
out = dict(zip(map(tuple, vals[mask]), counts[mask]))

Output:

{(163, 209, 247): 3}
Answered By: mozway

@Corralien’s answer with Counter is probably cleaner, although I imagine you’ll want to keep the uniqueness computation in numpy to take advantage of its optimised code.

values, counts = np.unique(img.reshape(-1, 3), axis=0, return_counts=True)

res = dict(
  (tuple(value), count)
    for (value, count) in zip(values, counts)
    if count < threshold  # define threshold accordingly
)
Answered By: motto
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.