DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on • Edited on

ToPILImage in PyTorch (1)

Buy Me a Coffee

*Memos:

ToPILImage() can convert an Image([..., C, H, W]), tensor or ndarray to a PIL(Pillow library) Image([H, W, C]) and doesn't scale its values to [0.0, 1.0] as shown below. *It's about no arguments:
*Memos:

  • The 1st argument for initialization is mode(Optional-Default:None-Type:PIL.Image mode): *Memos:
    • If it's None, a mode is automatically and basically set depending on img.
    • For 2D or the 1 channel(int) of 3D, e.g. [[0, 1, 2, 3]], [[[0]]], etc, 'I' is used.
    • For the 1 channel(float) of 2D or 3D, e.g. [[0], [1], [2], [3]], [[[0.]]], etc, 'L' is used.
    • For the 2 channels(int/float/complex/bool) of 3D, e.g. [[[0], [[1]]], [[[0.], [[1.]]], etc, 'LA' is used.
    • For the 3 channels(int/float/complex/bool) of 3D, e.g. [[[0], [[1]], [[2]]], [[[0.], [[1.]], [[2.]]], etc, 'RGB', 'YCbCr' or 'HSV' is used.
    • For the 4 channels(int/float/complex/bool) of 3D, e.g. [[[0], [[1]], [[2]], [[3]]], [[[0.], [[1.]], [[2.]], [[3.]]], etc, 'RGBA', 'CMYK' or 'RGBX' is used.
  • The 1st argument is img(Required-Type:PIL Image, Image or tensor/ndarray(int/float/complex/bool)): *Memos:
    • A tensor must be 2D or 3D.
    • A ndarray must be 2D or 3D.
    • Don't use img=.
  • v2 is recommended to use according to V1 or V2? Which one should I use?.
from torchvision.datasets import OxfordIIITPet
from torchvision.transforms.v2 import ToPILImage, ToImage, PILToTensor
import torch
import numpy as np

tp = ToPILImage()
tp = ToPILImage(mode=None)

tp
# ToPILImage()

print(tp.mode)
# None

Image_data = OxfordIIITPet(
    root="data",
    transform=ToImage()
)

Tensor_data = OxfordIIITPet(
    root="data",
    transform=PILToTensor()
)

tp = ToPILImage()

tp(Image_data) # It's still `Image`.
# Dataset OxfordIIITPet
#     Number of datapoints: 3680
#     Root location: data
#     StandardTransform
# Transform: ToImage()

tp(Tensor_data) # It's still `tensor`.
# Dataset OxfordIIITPet
#     Number of datapoints: 3680
#     Root location: data
#     StandardTransform
# Transform: ToTensor()

tp(Image_data[0])
tp(Tensor_data[0])
# (<PIL.Image.Image image mode=RGB size=394x500>, 0)

print(tp(Image_data[0][0]))
print(tp(Tensor_data[0][0]))
# <PIL.Image.Image image mode=RGB size=394x500 at 0x1A80D3608F0>

tp((torch.tensor([[0, 1, 2, 3]]), 0)) # int64
tp((torch.tensor([[0, 1, 2, 3]], dtype=torch.int64), 0))
tp(torch.tensor([[0, 1, 2, 3]]))
# TypeError: Input type int64 is not supported

tp((torch.tensor([[0, 1, 2, 3]], dtype=torch.int32), 0))
tp((torch.tensor([[[0, 1, 2, 3]]], dtype=torch.int32), 0))
# (<PIL.Image.Image image mode=I size=4x1>, 0)

tp((torch.tensor([[0., 1., 2., 3.]]), 0)) # float32
tp((torch.tensor([[0., 1., 2., 3.]], dtype=torch.float32), 0))
tp((torch.tensor([[0., 1., 2., 3.]], dtype=torch.float64), 0))
# (<PIL.Image.Image image mode=L size=4x1>, 0)

tp((torch.tensor([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j]]), 0)) # complex64
tp((torch.tensor([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j]],
    dtype=torch.complex64), 0))
# TypeError: Input type complex64 is not supported

tp((torch.tensor([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j]],
    dtype=torch.complex128), 0))
# TypeError: Input type complex128 is not supported

tp((torch.tensor([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j]],
    dtype=torch.complex32), 0))
# TypeError: Got unsupported ScalarType ComplexHalf

tp((torch.tensor([[True, False, True, False]]), 0)) # bool
tp((torch.tensor([[True, False, True, False]], dtype=torch.bool), 0))
# TypeError: Input type bool is not supported

tp((np.array([[0, 1, 2, 3]]), 0)) # int32
tp((np.array([[0, 1, 2, 3]], dtype=np.int32), 0))
# (<PIL.Image.Image image mode=I size=4x1>, 0)

tp((np.array([[0, 1, 2, 3]], dtype=np.int64), 0))
# TypeError: Input type int64 is not supported

tp((np.array([[0., 1., 2., 3.]]), 0)) # float64
tp((np.array([[0., 1., 2., 3.]], dtype=np.float64), 0))
tp((np.array([[0., 1., 2., 3.]], dtype=np.float32), 0))
# (<PIL.Image.Image image mode=L size=4x1>, 0)

tp((np.array([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j]]), 0)) # complex128
tp((np.array([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j]], dtype=np.complex128), 0))
# TypeError: Input type complex128 is not supported

tp((np.array([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j]], dtype=np.complex64), 0))
# TypeError: Input type complex64 is not supported

tp((np.array([[True, False, True, False]]), 0)) # bool
tp((np.array([[True, False, True, False]], dtype=bool), 0))
# TypeError: Input type bool is not supported
Enter fullscreen mode Exit fullscreen mode

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (0)

Tiugo image

Fast, Lean, and Fully Extensible

CKEditor 5 is built for developers who value flexibility and speed. Pick the features that matter, drop the ones that don’t and enjoy a high-performance WYSIWYG that fits into your workflow

Start now

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay