Home > database >  Mask 3d numpy array
Mask 3d numpy array

Time:06-10

Consider the following array as an image with three layers (red, green, blue). For each position in the image i want to test whether there is a specific value in one of the layers (e.g. 99). If that is true the values at the same position in the other layers shall be replaced by this specific value.

img = np.array([[[0, 99],
                 [2, 3]],
                     
                 [[4, 5],
                  [6, 7]],
                     
                 [[8, 9],
                  [10, 11]]])

The desired result would be:

img = [[[0, 99],
        [2, 3]],

       [[4, 99],
        [6, 7]],

       [[8, 99],
        [10, 11]]]

I am currently using the following code to fulfill the task.

c= []
for i in range(img.shape[1]):
    for j in range(img.shape[2]):
        if np.any(img[:, i, j]==99):
            c.append([99 for x in img[:, i, j]])
        else: c.append(img[:, i, j])

new_img = [np.array([row[i] for row in c]).reshape((2,2)).tolist() for i in range(len(c))]

However, this seems somewhat complicated. Can you recommend a better approach? Thank you for your help.

CodePudding user response:

The mask of pixels that are 99 in any channel is

mask = (img == 99).any(0)

You can apply this mask directly:

img[:, mask] = 99

Or as a one-liner:

img[:, (img == 99).any(0)] = 99

CodePudding user response:

You can do this by:

ind = np.argwhere(img == 99)[0, 1:]   # [0, 1]
img[:, ind[0], ind[1]] = 99
# [[[ 0 99]
#   [ 2  3]]
#  [[ 4 99]
#   [ 6  7]]
#  [[ 8 99]
#   [10 11]]]

which will work just on the first occurrence of 99. So, if you have more than one layer contain 99 or more than one count of 99 in each layer, do as @Mad solution.

  • Related