Home > Enterprise >  How do I merge multiple numpy masks into 1 single mask in python?
How do I merge multiple numpy masks into 1 single mask in python?

Time:03-26

I have an array of 2d masks that looks something like this:

[
  #mask0
 [[0.3,0.3],
  [0,0]],
  #mask1
  [[0.4,0],
  [0.4,0.4]]
]

And I want to merge the masks one after another, where every mask overrides the mask before it, (I don't want the sum of all masks). By override, I mean that if the value of the second mask wasn't 0, it will set the new value, otherwise keep what it was from the previous masks. So for this example, the result will be

[[0.4,0.3],
  [0.4,0.4]]]

Of course, In my case I don't have only 2 masks 2x2, I have multiple masks in a larger scale, this was just to demonstrate.

The masks represent circles in some grayscale value and I want to paste them one on top of another. Like this:

Purpose

How can I achieve this using NumPy with a clean and efficient code? And if there is a different way to approach this I'd love to hear it too.

CodePudding user response:

If you have a 3D array of masks arranged along the first axis, you can reduce along the first axis and merge your masks with np.where:

In [2]: import functools

In [3]: functools.reduce(lambda m0, m1: np.where(m1 == 0, m0, m1), masks)
Out[3]:
array([[0.4, 0.3],
       [0.4, 0.4]])

CodePudding user response:

If you have multiple images and you want apply on each image, you can use apply_along_axis like below:

from functools import reduce

images = np.random.rand(10, 4, 64, 64) # (n,masksAmount,imgSize,imgSize)
print(images.shape)

def apply_mask(image):
    image = reduce(lambda m0, m1: np.where(m1 == 0, m0, m1), image)
    return image

images = np.apply_along_axis(apply_mask, 1, images) # (n,imgSize,imgSize)
print(images.shape)

Output:

(10, 4, 64, 64) # shape
(10, 64, 64)    # shape

Example

image = np.array([[[0.3, 0.3], [0, 0]], [[0.4, 0], [0.4, 0.4]]])
images = np.repeat(image[None,...],4,0)
print(images.shape)

images = np.apply_along_axis(apply_mask, 1, images)
print(images.shape)
print(images)

Output:

(4, 2, 2, 2) # (n,masksAmount,imgSize,imgSize)

(4, 2, 2)    # (n,imgSize,imgSize)

# images =>
[[[0.4 0.3]
  [0.4 0.4]]

 [[0.4 0.3]
  [0.4 0.4]]

 [[0.4 0.3]
  [0.4 0.4]]

 [[0.4 0.3]
  [0.4 0.4]]]
  • Related