I'm trying to filter an image with shape (224, 224, 3) in RGB which has been loaded into a numpy array, where the last axis is the channels.
The logic is simple: look for specific pixel values across the 3 channels and assign a label to a new 1-Dim/1-Channel array. This is used for Segmentation Networks, where a pixel-wise label is assigned to represent the area of the object in the image.
The current loop looks like this:
mask = Image.open(args.input).convert('RGB')
array = np.array(img_mask)
h, w, c = array.shape
bg = np.zeros((w, h))
fg = np.zeros((w, h))
for i in range(0, h):
for k in range(0, w):
if np.array_equal(array[i,k], [0, 0, 0]):
bg[i,k] = 1
elif np.array_equal(array[i,k], [255, 200, 0]):
fg[i,k] = 2
label = np.stack((bg, fg), axis=0)
This produces a (2, 224, 224) where axis = 0 is the channels and then axis=1 has the pixel labels.
I have tried to replace the two for loops using np.where however, the result is still a 3D array, whereas what I want is a 1D array, created for each pixel coordinate which matches the condition:
bg = np.where(array == [0, 0, 0], 1, 0)
fg = np.where(array == [255, 200, 0], 2, 0)
label = np.stack((bg, fg), axis=0)
However here I get: (2, 224, 224, 3)
The current for loop implementation is painfully slow, and I suspect this can be done using built-in numpy functions, but I've failed to achieve the same result so far.