Apply transform on numpy arrays

If I have the dataset as two arrays X and y as images and labels, both are numpy arrays. I want to apply transforms (like those from models given by the pretrainedmodels package), how can apply them on my data, especially as the way as datasets.ImageFolder.

My numpy arrays are converted from PIL Images, and I found how to convert numpy arrays to dataset loaders here.

1 Like

with not use toTensor() in your transform?

example here:

https://pytorch.org/docs/master/torchvision/transforms.html#torchvision.transforms.Compose

you can then reconvert your tensors to numpy using .numpy()

example:

https://pytorch.org/tutorials/beginner/former_torchies/tensor_tutorial.html#numpy-bridge

Thanks @yvanscher. But it seems that transforms accept img as input, not tensors. See the pil_loader function and DatasetFolder.__getitem__ method here.

Now I decide to save the PIL image in the numpy arrays, without converting to numpy array with np.array(img). Then I might be able to use transform, and then TensorDataset and DataLoader ā€¦

You can also write a custom transformer which is very easy:

class Resize:
    def __init__(self, size):
        assert isinstance(size, int) or (isinstance(size, Iterable) and len(size) == 2)
        if isinstance(size, int):
            self._size = (size, size)
        else:
            self._size = size

    def __call__(self, img: np.ndarray):
        resize_image = skimage.transform.resize(img, self._size)
        # the resize will return a float64 array
        return skimage.util.img_as_ubyte(resize_image)
1 Like

I love this image augmentation library called imgaug. Sooooo nice!

1 Like

Docs says ToTensor() transform accepts PIL image or numpy array:

https://pytorch.org/docs/stable/torchvision/transforms.html#torchvision.transforms.ToTensor

Iā€™m super late to the party but I came across this great repo that rewrote the base class to just use numpy arrays for the transformations

Please look at the following example:

import numpy as np
from torchvision import transforms

X = np.random.randint(low=0, high=255, size=(32,32,3), dtype=np.unit8)  # an image in ndarray format
your_transforms = transforms.Compose([transforms.CenterCrop(10),transforms.ToTensor(),])  # a set of transformations
if isinstance(X, np.ndarray):
    your_transforms.transforms.insert(0, transforms.ToPILImage())

Now given what you found on the other page, we can do this:

from torchvision.datasets import VisionDataset

class BasicVisionDataset(VisionDataset):
    def __init__(self, images, targets, transform=None, target_transform=None):
        if isinstance(images, np.ndarray):
            transform.transforms.insert(0, transforms.ToPILImage())
        super(BasicVisionDataset, self).__init__(root=None, transform=transform, target_transform=target_transform)
        assert len(images) == len(targets)

        self.images = images
        self.targets = targets

    def __getitem__(self, index):
        return self.transform(self.images[index]), self.targets[index]

    def __len__(self):
        return len(self.targets)

Please let me know if this works.