I have image segmentation project, and ground truth labels given as images where pixel value stands for the label. I need to resize the images and labels, while keeping the labels in the same value set.
Lets create dummy data
from skimage.transform import rescale, resize
from scipy import ndimage
from PIL import Image
import cv2
mask = np.zeros((30,20), dtype=np.uint16)
mask[22:26,12:30]=70
mask[25:27,14:17]=30
print('original label', mask.shape, np.unique(mask))
Outputs: original label shape: (30, 20) original label values: [ 0 30 70]
I need to resize label, so the result will have only 0, 30, 70 values.
What I triedskimage_resized = resize(mask, (mask.shape[0]//2, mask.shape[1]//2), mode='constant')
print(skimage_resized.shape, np.unique(mask_resized))
skimage_rescale = rescale(mask, 1.0/2.0, mode='constant')
print(skimage_rescale.shape, np.unique(mask_resized))
ndimage_resized = ndimage.interpolation.zoom(mask, 0.5)
print(ndimage_resized.shape, np.unique(mask_resized))
cv2_resized = cv2.resize(mask, (mask.shape[0]//2, mask.shape[1]//2),
interpolation=cv2.INTER_NEAREST)
print(cv2_resized.shape, np.unique(mask_resized))
mask_pil = Image.fromarray(mask, mode=None)
pil_resized = mask_pil.thumbnail((mask.shape[0]//2, mask.shape[1]//2), Image.NEAREST)
print(skimage_resized.shape, np.unique(pil_resized))
Output:
(15, 10) [ 0 5 6 28 29 30 31 61 62 65 70 71 74 75 76]
(15, 10) [ 0 5 6 28 29 30 31 61 62 65 70 71 74 75 76]
(15, 10) [ 0 5 6 28 29 30 31 61 62 65 70 71 74 75 76]
(10, 15) [ 0 5 6 28 29 30 31 61 62 65 70 71 74 75 76]
(15, 10) [None]
Found a solution with openCV.
import numpy as np
import cv2
resizeto = 2
small_lable = cv2.resize(mask, (mask.shape[1]//resizeto,
mask.shape[0]//resizeto),
interpolation=cv2.INTER_NEAREST)
small_lable = (np.array(small_lable)).astype('uint8')
print(small_lable.shape, np.unique(small_lable))
plt.imshow(small_lable)
output:
(15, 10) [ 0 30 70]