【Python】torchvision—transforms库讲解、图像预处理

【Python】数据预处理——torchvision.transforms

1. 介绍

首先,在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)

2. 举例说明

2.1 导入所需包

import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

2.2 class torchvision.transforms.Compose(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的类型。具体的可以看后面的使用。

2.3 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])

2.4 class torchvision.transforms.ToPILImage

将shape为(C,H,W)的Tensor或shape为(H,W,C)的numpy.ndarray 转换成PIL.Image,值不变(注意与Totensor的区别)。还有要注意是这个方法好像只支持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

2.5 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 的后面。

2.6 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])

2.7 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])

多切几次,获得的图像是不同的,但是大小相同。

2.8 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])

2.9 class torchvision.transforms.RandomResizedCrop(size, interpolation=2)

这个函数是可以说是crop和resize的合体。

  • 先将给定的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])

2.9 class torchvision.transforms.Pad(padding, fill=0)

transforms.Pad class torchvision.transforms.Pad(padding, fill=0, padding_mode=‘constant’)

  • 功能:对图像进行填充
  • 参数:
    • padding-(sequence or int, optional),此参数是设置填充多少个pixel。
      • 当为int时,图像上下左右均填充int个,例如padding=4,则上下左右均填充4个pixel,若为3232,则会变成4040;
      • 当为sequence时,若有2个数,则第一个数表示左右扩充多少,第二个数表示上下的。当有4个数时,则为左,上,右,下。
    • fill-(int or tuple) 填充的值是什么(仅当填充模式为constant时有用)。
      • int时,各通道均填充该值,
      • 当长度为3的tuple时,表示RGB通道需要填充的值。
    • padding_mode- 填充模式,这里提供了4种填充模式,
      • constant,常量。
      • edge,按照图片边缘的像素值来填充。
      • reflect
      • symmetric

3. 参考

【1】https://blog.csdn.net/kejizuiqianfang/article/details/88947790

猜你喜欢

转载自blog.csdn.net/qq_51392112/article/details/129679819
今日推荐