【问题标题】:PyTorch - How to use "toPILImage" correctlyPyTorch - 如何正确使用“toPILImage”
【发布时间】:2021-03-28 13:25:11
【问题描述】:

我想知道,我是否正确使用了来自 torchvision 的toPILImage。我想使用它来查看将初始图像转换应用于数据集后图像的外观。

当我在下面的代码中使用它时,出现的图像具有奇怪的颜色,例如 this one。原始图像是常规的 RGB 图像。

这是我的代码:

import os
import torch
from PIL import Image, ImageFont, ImageDraw
import torch.utils.data as data
import torchvision
from torchvision import transforms    
import matplotlib.pyplot as plt

# Image transformations
normalize = transforms.Normalize(
    mean=[0.485, 0.456, 0.406],
    std=[0.229, 0.224, 0.225]
    )
transform_img = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(256),
    transforms.ToTensor(),
    normalize ])

train_data = torchvision.datasets.ImageFolder(
    root='./train_cl/',
    transform=transform_img
    )
test_data = torchvision.datasets.ImageFolder(
    root='./test_named_cl/',
    transform=transform_img                                             
    )

train_data_loader = data.DataLoader(train_data,
    batch_size=4,
    shuffle=True,
    num_workers=4) #num_workers=args.nThreads)

test_data_loader = data.DataLoader(test_data,
    batch_size=32,
    shuffle=False,
    num_workers=4)        

# Open Image from dataset:
to_pil_image = transforms.ToPILImage()
my_img, _ = train_data[248]
results = to_pil_image(my_img)
results.show()

编辑:

我必须在 Torch 变量上使用 .data 来获取张量。 我还需要在转置之前重新调整 numpy 数组。我找到了一个可行的解决方案here,但它并不总是很好用。我怎样才能做得更好?

for i, data in enumerate(train_data_loader, 0):
    img, labels = data
    img = Variable(img)
    break

image = img.data.cpu().numpy()[0]

# This worked for rescaling:
image = (1/(2*2.25)) * image + 0.5

# Both of these didn't work:
# image /= (image.max()/255.0)
# image *= (255.0/image.max())

image = np.transpose(image, (1,2,0))
plt.imshow(image)
plt.show() 

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    您可以使用 PIL 图像,但实际上并没有像往常一样加载数据。

    试试这样的:

    import numpy as np
    import matplotlib.pyplot as plt
    
    for img,labels in train_data_loader:
        # load a batch from train data
        break
    
    # this converts it from GPU to CPU and selects first image
    img = img.cpu().numpy()[0]
    #convert image back to Height,Width,Channels
    img = np.transpose(img, (1,2,0))
    #show the image
    plt.imshow(img)
    plt.show()  
    

    作为更新(2021 年 2 月 10 日):

    import torchvision.transforms.functional as F
    # load the image (creating a random image as an example)
    img_data = torch.ByteTensor(4, 4, 3).random_(0, 255).numpy()
    pil_image = F.to_pil_image(img_data)
    

    或者

    import torchvision.transforms as transforms
    img_data = torch.ByteTensor(4, 4, 3).random_(0, 255).numpy()
    pil_image = transforms.ToPILImage()(img_data)
    

    第二种形式可以与pytorch中的dataset loader集成,也可以直接调用。

    我添加了修改后的 to_pil_image here

    基本上它符合我在 2018 年的建议,但现在已集成到 pytorch 中。

    【讨论】:

    • 请看我上面的编辑。我让它工作,但它说“浮点图像 RGB 值必须在 0..1 范围内。”。所以我想,我需要重新调整 numpy 数组。我发现“image = (1/(2*2.25)) * image + 0.5”,它有效,但数字似乎是任意的,有时会显示在结果图像中。你知道一种方法可以对任何图像都更健壮吗?
    • 为了简单易读,我更喜欢这个:image = (image - image.min()) / (image.max() - image.min()) 上一个有错误。
    【解决方案2】:

    我会用这样的东西

    # Open Image from dataset:
    my_img, _ = train_data[248]
    results = transforms.ToPILImage()(my_img)
    results.show()
    

    【讨论】:

      猜你喜欢
      • 2020-10-18
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 2018-11-01
      • 2019-05-12
      • 2019-11-16
      • 2019-06-24
      • 1970-01-01
      相关资源
      最近更新 更多