使用Pytorch进行模型训练时,经常会遇到数据格式的错误,不同的数据类型之间的相互转换十分有用,总结如下。
一、Tensor与PILImage
使用PIL包读图片并将其转化为tensor类型,再转化为PIL类型
import torch
from PIL import Image
import torchvision
img = Image.open('datasets\\input_test\\3063.jpg')
print(type(img))
trans_totensor = torchvision.transforms.ToTensor()
img_tensor = trans_totensor(img)
print(type(img_tensor))
trans_toPIL = torchvision.transforms.ToPILImage()
img_PIL = trans_toPIL(img_tensor)
print(type(img_PIL))
输出:
<class 'PIL.JpegImagePlugin.JpegImageFile'>
<class 'torch.Tensor'>
<class 'PIL.Image.Image'>
二、Tensor与Numpy
使用cv2读入图片得到的数据类型是Numpy类型,将其转化为tensor
import cv2
import torch
import torchvision
img = cv2.imread('datasets\\input_test\\3063.jpg')
print(type(img), img.shape)
trans_totensor = torchvision.transforms.ToTensor()
img_tensor = trans_totensor(img)
print(type(img_tensor), img_tensor.shape)
img_tensor = img_tensor.reshape((img_tensor.shape[1], img_tensor.shape[2],-1))
print(type(img_tensor), img_tensor.shape)
img_numpy=img_tensor.numpy()
print(type(img_numpy), img_numpy.shape)
print(img_numpy == img)
输出:
<class 'numpy.ndarray'> (159, 239, 3)
<class 'torch.Tensor'> torch.Size([3, 159, 239])
<class 'torch.Tensor'> torch.Size([159, 239, 3])
<class 'numpy.ndarray'> (159, 239, 3)
[[[False False False]
[False False False]
[False False False]
...
注意,totensor操作会将numpy和PIL格式的图片转换为[0,1]之间的小数,并且改变张量的形状,因此直接从tensor转为numpy得到的是小数,与读入的numpy类型图片内容完全不同。
官方文档解释如下:
Converts a PIL Image or numpy.ndarray (H x W x C) in the range [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0] if the PIL Image belongs to one of the modes (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1) or if the numpy.ndarray has dtype = np.uint8
In the other cases, tensors are returned without scaling.
三、PIL与Numpy
from PIL import Image
import numpy as np
img = Image.open('datasets\\input_test\\3063.jpg')
print(type(img),img.size)
img_np=np.array(img)
print(type(img_np),img_np.shape)
img_PIL=Image.fromarray(img_np)
print(type(img_PIL),img_PIL.size)
输出:
<class 'PIL.JpegImagePlugin.JpegImageFile'> (239, 159)
<class 'numpy.ndarray'> (159, 239, 3)
<class 'PIL.Image.Image'> (239, 159)
注意注意注意,cv2和PIL.Image读图后转化为Numpy类型,二者通道不同,同一通道数值也不同!!!,cv2读入通道数为‘BGR’,PIL为‘RGB’
四、图像颜色表示方式
RGB HSL HSV