How to select all non-black pixels in a NumPy array?
You should use np.any
instead of np.all
for the second case of selecting all but black pixels:
np.any(image != [0, 0, 0], axis=-1)
Or simply get a complement of black pixels by inverting a boolean array by ~
:
black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
non_black_pixels_mask = ~black_pixels_mask
Working example:
import numpy as np
import matplotlib.pyplot as plt
image = plt.imread('example.png')
plt.imshow(image)
plt.show()
image_copy = image.copy()
black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
non_black_pixels_mask = np.any(image != [0, 0, 0], axis=-1)
# or non_black_pixels_mask = ~black_pixels_mask
image_copy[black_pixels_mask] = [255, 255, 255]
image_copy[non_black_pixels_mask] = [0, 0, 0]
plt.imshow(image_copy)
plt.show()
In case if someone is using matplotlib to plot the results and gets completely black image or warnings, see this post: Converting all non-black pixels into one colour doesn't produce expected output
Necessity: Need matrix with this shape = (any,any,3)
Solution:
COLOR = (255,0,0)
indices = np.where(np.all(mask == COLOR, axis=-1))
indexes = zip(indices[0], indices[1])
for i in indexes:
print(i)
Solution 2:
get interval of specific color, for example RED:
COLOR1 = [250,0,0]
COLOR2 = [260,0,0] # doesnt matter its over limit
indices1 = np.where(np.all(mask >= COLOR1, axis=-1))
indexes1 = zip(indices[0], indices[1])
indices2 = np.where(np.all(mask <= COLOR2, axis=-1))
indexes2 = zip(indices[0], indices[1])
# You now want indexes that are in both indexes1 and indexes2
Solution 3 - PROVED to be WORKING
If previous doesnt work, then there is one solution that works 100%
Transform from RGB channel to HSV. Make 2D mask from 3D image. 2D mask will contain Hue value. Comparing Hues is easier than RGB as Hue is 1 value while RGB is vector with 3 values. After you have 2D matrix with Hue values, do like above:
HUE1 = 0.5
HUE2 = 0.7
indices1 = np.where(HUEmask >= HUE1)
indexes1 = zip(indices[0], indices[1])
indices2 = np.where(HUEmask <= HUE2)
indexes2 = zip(indices[0], indices[1])
You can dothe same for Saturation and Value.