I am wondering if there is any torch function that interpolates an image in an in-painting way.
I find that the function torch.nn.functional.interpolate
only expands or squeezes the image, but cannot fill the values within a masked image.
This may sound confusing, so I made some code and diagrams to make it clear:
import numpy as np
import torch
import torch.nn.functional as F
from PIL import Image
def gen_banded_mask(img, num_bands=10, band_width=10):
# accept [H, W, C]
height, weight = img.shape[:2]
masked_indices = []
mask = np.ones_like(img, dtype=img.dtype)
rand_hs = np.random.choice(height, num_bands, replace=False)
for h in rand_hs:
h0 = max(h - band_width, 0)
h1 = min(h + band_width, height)
masked_indices.extend([*range(h0, h1)])
mask[h0:h1, ...] = 0
unmasked_indices = [_ for _ in range(height) if _ not in masked_indices]
return mask, sorted(unmasked_indices)
img_path = '../bin/sample-rbg.png'
img = np.asarray(Image.open(img_path).convert('RGB')) / 255.0
mask, unmasked_hs = gen_banded_mask(img, num_bands=20)
img_masked = img * mask
img_reduced = img[unmasked_hs, ...] # image with only the unmasked rows
tensor_reduced = torch.from_numpy(img_reduced).float().permute(2, 0, 1).unsqueeze(0) # [1, C, H, W]
tensor_interp = F.interpolate(tensor_reduced, size=img.shape[:2], mode='bilinear')
img_interp = tensor_interp.squeeze(0).permute(1, 2, 0).numpy() # This does not in-paint but just expand the image
Now let’s show [img, mask, img_masked, img_interp]
. You can see my way of applying F.interpolate
does not in-paint the masked pixels in the image but can only expand the unmasked part: