torchvision transform库学习总结
参考了https://www.pytorchtutorial.com/docs/torchvision/torchvision-transform/
首先,在torchvision transform库中,大致有以下几类方法
1.一个类似数组的操作
class torchvision.transforms.Compose(transforms)
2.各种数据类型的转换
class torchvision.transforms.ToTensor
class torchvision.transforms.ToPILImage
3.对Tensor进行变换
class torchvision.transforms.Normalize(mean, std)
4.对PIL.Image进行变换
class torchvision.transforms.CenterCrop(size)
class torchvision.transforms.RandomCrop(size, padding=0)
class torchvision.transforms.RandomHorizontalFlip()
class torchvision.transforms.RandomResizedCrop(size, interpolation=2)
class torchvision.transforms.Pad(padding, fill=0)
在运行本教程之前,请先导入包:
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
----------------------------------------------------------------------------------------------------------
同时我在项目的目录下面的data文件夹放了一个image.jpg图片
原图是
----------------------------------------------------------------------------------------------------------
下面将按顺序介绍:
class torchvision.transforms.Compose(transforms)
将多个transform组合起来使用。
from torchvision import transforms as transforms
transform = transforms.Compose([
transforms.RandomCrop(32, padding=4), #先四周填充0,在吧图像随机裁剪成32*32
transforms.RandomHorizontalFlip(), #图像一半的概率翻转,一半的概率不翻转
transforms.RandomRotation((-45,45)), #随机旋转
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.229, 0.224, 0.225)), #R,G,B每层的归一化用到的均值和方差
])
这里在执行的时候会按照顺序执行,先执行transforms.RandomCrop(32, padding=4)
,最后执行transforms.Normalize((0.4914, 0.4822, 0.4465), (0.229, 0.224, 0.225))
,所以这里一定要注意类型的问题,这些方法有的使用的是Tensor
类型,有些是PIL.Image
的类型。具体的可以看后面的使用
class torchvision.transforms.ToTensor
把一个取值范围是[0,255]的PIL.Image或者shape为(H,W,C)的numpy.ndarray,转换成形状为[C,H,W],取值范围是[0,1.0]的torch.FloadTensor
输入代码
data = np.random.randint(0, 255, size=300)
img = data.reshape(10,10,3)
print(img.shape)
img_tensor = transforms.ToTensor()(img) # 转换成tensor
print(img_tensor.shape)
输出结果
(10, 10, 3)
torch.Size([3, 10, 10])
class torchvision.transforms.ToPILImage
将shape为(C,H,W)的Tensor或shape为(H,W,C)的numpy.ndarray转换成PIL.Image,值不变。但是要注意是这个方法好像只支持uint8的数据类型
输入代码
data = np.random.randint(0, 255, size=300, dtype='uint8')
img = data.reshape(10,10,3)
print(img.shape)
img_PIL = transforms.ToPILImage()(img)
print(img_PIL.size)
print(img_PIL.mode)
输出结果
(10, 10, 3)
(10, 10)
RGB
class torchvision.transforms.Normalize(mean, std)
给定均值:(R,G,B) 方差:(R,G,B),将会把Tensor正则化。即:Normalized_image=(image-mean)/std。
这个就不解释了,输入mean和std,直接执行公式Normalized_image=(image-mean)/std
,但是要注意的是这个处理的数据要求是Tensor类型的。所以在使用class torchvision.transforms.Compose(transforms)
的时候要注意将这个类放在class torchvision.transforms.ToTensor
后面
class torchvision.transforms.CenterCrop(size)
将给定的PIL.Image进行中心切割,得到给定的size,size可以是tuple,(target_height, target_width)。size也可以是一个Integer,在这种情况下,切出来的图片的形状是正方形。
输入代码
transform = transforms.Compose([transforms.CenterCrop(500), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
输出
(606, 910, 3)
torch.Size([3, 500, 500])
class torchvision.transforms.RandomCrop(size, padding=0)
切割中心点的位置随机选取。size可以是tuple也可以是Integer。这个和上面的那个方法比较类似,但是这个切的比较随机了,切好的图片的中心点是从原图中随机选择的,当然选择的中心点肯定是可以保证切出来的图片满足size的要求的
输入代码
transform = transforms.Compose([transforms.RandomCrop(500, padding=100), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
输出结果
(606, 910, 3)
torch.Size([3, 500, 500])
多切几次,结果不同
class torchvision.transforms.RandomHorizontalFlip()
随机水平翻转给定的PIL.Image,概率为0.5。即:一半的概率翻转,一半的概率不翻转。
输入代码,这个可以多运行几次,你会发现不一样的
transform = transforms.Compose([transforms.RandomHorizontalFlip(), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
输出
(606, 910, 3)
torch.Size([3, 606, 910])
你可以看到这个图片和原图进行了镜像反转
class torchvision.transforms.RandomResizedCrop(size, interpolation=2)
先将给定的PIL.Image随机切,然后再resize成给定的size大小。这个函数已经改成了RandomResizedCrop
,以前的RandomSizedCrop
已经被弃用了,这里是使用插值的方式将随机切的图片填充成你需要的大小,但是size只能是一个整数,也就是说只能切出来一个正方形的
输入代码
transform = transforms.Compose([transforms.RandomResizedCrop(500, interpolation=1), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
输出结果
(606, 910, 3)
torch.Size([3, 500, 500])
class torchvision.transforms.Pad(padding, fill=0)
将给定的PIL.Image的所有边用给定的pad value填充。 padding:要填充多少像素 fill:就是一个很简单的填充函数,这里就不演示了