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