1

I would like to resize, and specifically shrink, a mask (2D array of 1s and 0s) so that any pixel in the low-resolution-mask that maps to a group of pixels in the high-resolution-mask (original) containing at least one value of 1 will be set to 1 itself (example at bottom).

I've tried using cv2.resize() using cv2.INTER_MAX but it returned an error:

error: OpenCV(4.6.0) /io/opencv/modules/imgproc/src/resize.cpp:3927: error: (-5:Bad argument) Unknown interpolation method in function 'resize'

It doesn't seem that Pillow Image or scipy have an interpolation method to do so.

I'm looking for a solution for the defined shrink_max()

>>> orig_mask = [[1,0,0],[0,0,0],[0,0,0]]
>>> orig_mask
[[1,0,0]
,[0,0,0]
,[0,0,0]]
>>> mini_mask = shrink_max(orig_mask, (2,2))
>>> mini_mask
[[1,0]
,[0,0]]
>>> mini_mask = shrink_max(orig_mask, (1,1))
>>> mini_mask
[[1]]
Frogrammer
  • 23
  • 3

1 Answers1

1

I'm not aware of a direct method but try this for shrinking the mask to half-size, i.e. each low-res pixel maps to 4 original pixels (modify to any ratio as per your needs):

import numpy as np

orig_mask = np.array([[1,0,0],[0,0,0],[0,0,0]])

# first make the original mask divisible by 2
pad_row = orig_mask.shape[0] % 2
pad_col = orig_mask.shape[1] % 2

# i.e. pad the right and bottom of the mask with zeros
orig_mask_padded = np.pad(orig_mask, ((0,pad_row), (0,pad_col)))

# get the new shape
new_rows = orig_mask_padded.shape[0] // 2
new_cols = orig_mask_padded.shape[1] // 2

# group the original pixels by fours and max each group 
shrunk_mask = orig_mask_padded.reshape(new_rows, 2, new_cols, 2).max(axis=(1,3))

print(shrunk_mask)

Check working with submatrixes here: Numpy: efficiently sum sub matrix m of M


Here's the complete function for shrinking to any desired shape:

def shrink_max(mask, shrink_to_shape):
    r, c = shrink_to_shape
    m, n = mask.shape
    padded_mask = np.pad(mask, ((0, -m % r), (0, -n % c)))
    pr, pc = padded_mask.shape
    return padded_mask.reshape(r, pr // r, c, pc // c).max(axis=(1, 3))

For example print(shrink_max(orig_mask, (2,1))) returns:

[[1]
 [0]]
isCzech
  • 313
  • 1
  • 1
  • 7