Negative of an image using Pytorch transforms

I am trying to invert the images in my dataset. I know it is possible using OpenCV but I don’t know whether it is possible using torchvision.transforms. Any pointers would be appreciated.

3 Likes

Hi,

Transforms internally does not provide such a transform but as its core is PIL image library, you can simply use functions available in PIL to create custom transforms. Here is the one I extended for Negative:


import PIL.ImageOps

def to_negative(img):
    img = PIL.ImageOps.invert(img)
    return img

class Negative(object):
    """Convert image to negative.

    Args:
        

    Returns:
        PIL Image: Negative version of the input.
         
    """
    def __init__(self):
        pass
    
    def __call__(self, img):
        """
        Args:
            img (PIL Image): Image to be converted to Negative.

        Returns:
            PIL Image: Negatived image.
        """
        return to_negative(img)

t = transforms.Compose([transforms.CenterCrop(10), 
                        Negative()])

Bests

1 Like

You can use torchvision.transforms.functional.invert() from the torchvision transforms library.

1 Like

torchvision.transforms.functional.invert() seems to be discontinued or something. I get AttributeError: module ‘torchvision.transforms.functional’ has no attribute ‘invert’ when I try to use it. My torch version is 1.7.1

Most likely you are using an older torchvision release. Note that torch and torchvision use different versioning and are not the same lib.

3 Likes

I’m trying to use torchvision.transforms.functional.invert() on an entire dataset,
Like the following:

train_ds = datasets.MNIST('./data', train=True, download=True,
                       transform=transforms.Compose([
                           transforms.ToTensor(),
                           transforms.functional.invert()
                       ]))

But I got error:
TypeError: invert() missing 1 required positional argument: 'img'

Is there a way to invert all images in a dataset without looping over each image?

You are trying to use the functional API operation in a transformation, which won’t work directly, so wrap it in e.g. transforms.Lambda or write a custom transformation class.
This should work:

data = torch.randn(100, 3, 224, 224)
out = torchvision.transforms.functional.invert(data)

transform = torchvision.transforms.Compose([
    torchvision.transforms.Lambda(lambda x: torchvision.transforms.functional.invert(x))
])
out = transform(data)

Also, since you are passing the current transform to the MNIST dataset, it will be applied on each sample, not the entire dataset.

1 Like

Is torchvision.transforms.Lambda(transforms.functional.invert) ok? It does what I want. I find I’m having issues with pickling the lambda in the above code snippet.

Yes, your code seems to work fine, too.

1 Like