I'm trying to mark regions of an image array (224x224) to be ignored based on the value of a segmentation network's class mask (16x16). Previous processing means that unwanted regions will be labelled as -1. I want to be able to set the value of all regions of the image where the class mask reports -1 to some nonsense value (say, 999), but maintain the shape of the array (224x224). A concise example of what I mean is below, using a 4x4 image and 2x2 mask.
# prefilter
image = 1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
mask = -1 4
-1 5
# postfilter
image_filtered = 999 999 3 4
999 999 7 8
999 999 2 3
999 999 6 7
Is there an efficient way to do this modification?
CodePudding user response:
Here's some code I got to work. It does require the mask and the image to have the same aspect ratio, and be integer multiples of each others sizes.
import numpy as np
image = np.array([[1,2,3,4],
[5,6,7,8],
[9,1,2,3],
[4,5,6,7]])
mask = np.array([[-1,4],
[-1,5]])
def mask_image(image, mask, masked_value):
scale_factor = image.shape[0]//mask.shape[0] # how much the mask needs to be scaled up by to match the image's size
resized_mask = np.kron(mask, np.ones((scale_factor,scale_factor))) # resize the mask (magic)
return(np.where((resized_mask==-1),masked_value,image)) # where the mask==-1, return the masked value, else return the value of the original array.
print(mask_image(image, mask, 999))
I used np.kron to resize an array after seeing this answer.
This function is extremely fast, it took ~2 sec to mask a 1920x1080 image with a 1920x1080 mask.
EDIT: Use what @Jérôme Richard said in their comment.
