对于图像分类任务,由于不需要标注真实框,在进行数据增强的过程中只需要对图像进行变换,标签保持原样,因此目标检测中使用的全部数据增强方法都可以直接用于图像分类任务,非常的方便。所以这一篇主要聊一聊PyTorch提供的各种数据增强方法。
Pytorch官方提供的大多数数据增强方法都存放在torchvision.transforms这个python文件中,对源代码感兴趣的话可以直接打开这个文件。
一般常用的函数主要是:Resize()、CenterCrop()、RandomRotation()、RandomHorizontalFlip()、RandomVerticalFlip()、Compose()、ToTensor()、Normalize()等。
0. 准备工作
用于展示数据增强效果的图像是COCO数据集的000000000030.jpg:
Figure1:图像的高和宽分别是428*640
1. Resize()
Resize(size, interpolation=InterpolationMode.BILINEAR, max_size=None, antialias=‘warn’)
类功能:该函数用于将图像缩放到指定的大小。
参数列表:
size:一般输入一个元组(h, w),图像会缩放到这个大小;如果只输入一个整数,那么图像的短边会缩放到这个长度,长边会按缩放比例缩放。
interpolation:插值策略,默认是双线性插值法。
max_size:图像长边最大缩放长度,长边不可以超出这个最大长度。
antialias:抗锯齿,对于张量,只影响双线性插值和双三次插值模式的张量;对于PIL图像,只能用于双线性插值和双三次插值模式,对于其它模式,没有意义。一般使用默认值就可以了。
示例代码如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
resize = transforms.Resize(224)
img = resize(img)
img = np.array(img)
img = img[:, :, ::-1]
cv2.imwrite(r"./class_imgs/resize.jpg", img)
程序运行结果:
Figure2:图像的高和宽分别是224*334
2. CenterCrop()
CenterCrop(size)
类功能:按照size的大小截取图像的中心区域。
参数列表:
size:一般是(h, w),如果输入一个整数size,那么按照(size, size)截取。
示例代码如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
centercrop = transforms.CenterCrop(224)
img = centercrop(img)
img = np.array(img)
img = img[:, :, ::-1]
cv2.imwrite(r"./class_imgs/centercrop.jpg", img)
程序运行结果:
Figure3:图像的高和宽分别是224*224
3. RandomRotation()
RandomRotation(degrees, interpolation=InterpolationMode.NEAREST, expand=False, center=None, fill=0)
类功能:随机旋转图像。
参数列表:
degrees:输入一个整数degrees,那么旋转的范围是(-degrees, degree),或者输入一个元组(min, max)。
interpolation:插值策略,默认是最邻近插值。
expand:扩展输出使其可以容纳旋转后的图像。
center:旋转中心,默认是图像的中心点。
fill:旋转图像之外的填充值。
示例代码如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
randomrotation = transforms.RandomRotation(degrees=(-5, 5), expand=True, fill=114)
img = randomrotation(img)
img = np.array(img)
img = img[:, :, ::-1]
cv2.imwrite(r"./class_imgs/randomrotation.jpg", img)
程序运行结果:
Figure4:图像的高和宽分别是472*670
4. RandomHorizontalFlip()
RandomHorizontalFlip(p=0.5)
类功能:以一定的概率水平翻转图像。
参数列表:
p:浮点数,翻转的概率值。
示例代码如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
randomHorizontalFlip = transforms.RandomHorizontalFlip(0.5)
img = randomHorizontalFlip(img)
img = np.array(img)
img = img[:, :, ::-1]
cv2.imwrite(r"./class_imgs/randomHorizontalFlip.jpg", img)
程序运行结果:
Figure5:图像的高和宽分别是428*640
5. RandomVerticalFlip()
RandomVerticalFlip(p=0.5)
类功能:以一定的概率垂直翻转图像。
参数列表:
p:浮点数,翻转的概率值。
示例代码如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
randomVerticalFlip = transforms.RandomVerticalFlip(0.5)
img = randomVerticalFlip(img)
img = np.array(img)
img = img[:, :, ::-1]
cv2.imwrite(r"./class_imgs/randomVerticalFlip.jpg", img)
程序运行结果:
Figure6:图像的高和宽分别是428*640
6. Compose()
Compose(transforms)
类功能:可以将多个函数组合在一起使用
参数列表:
transforms:一个tranforms对象的列表。
示例代码如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
transformsAll = transforms.Compose([
transforms.Resize(224),
transforms.RandomRotation(degrees=(-5, 5), expand=True, fill=114),
transforms.RandomVerticalFlip(0.5),
])
img = transformsAll(img)
img = np.array(img)
img = img[:, :, ::-1]
cv2.imwrite(r"./class_imgs/transformsAll.jpg", img)
程序运行结果:
Figure7:图像的高和宽分别是244*348
7. ToTensor()
ToTensor()
类功能:将一个PIL图像或者ndarray数组转换成tensor,维度会从(H, W, C)转换成(C, H, W),数值范围会从[0, 255]转换成[0, 1.0]。
示例代码如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
transformsAll = transforms.Compose([
transforms.Resize(224),
transforms.RandomRotation(degrees=(-5, 5), expand=True, fill=114),
transforms.RandomVerticalFlip(0.5),
transforms.ToTensor(),
])
img = transformsAll(img)
print(type(img))
img_array = img.numpy()
img_array = np.transpose(img_array, (1, 2, 0))
img_array = img_array[:, :, ::-1]
img_array = img_array * 255
img_array = img_array.astype(np.uint8)
cv2.imwrite(r"./class_imgs/totensor.jpg", img_array)
程序运行结果:
<class 'torch.Tensor'>
Figure8:图像的高和宽分别是242*346
8. Normalize()
Normalize(mean, std, inplace=False)
类功能:对图像张量进行归一化操作。
参数列表:
mean:均值列表,[mean[0], …, mean[N]]
std:标准差列表,[std[0], …, std[N]]
inplace:直接对输入数据进行操作,不另外存储。
示例程序如下:
import cv2
from torchvision import transforms
from PIL import Image
import numpy as np
import torch
img_path = r"G:\datasets\COCO\000000000030.jpg"
img = Image.open(img_path).convert("RGB")
transformsAll = transforms.Compose([
transforms.Resize(224),
transforms.RandomRotation(degrees=(-5, 5), expand=True, fill=114),
transforms.RandomVerticalFlip(0.5),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), # 一般都使用ImageNet数据集的均值和标准差
])
img = transformsAll(img)
print(type(img))
# img 是一个归一化的图像,其形状为 (C, H, W)
mean = torch.tensor([0.485, 0.456, 0.406]).view(3, 1, 1)
std = torch.tensor([0.229, 0.224, 0.225]).view(3, 1, 1)
# 对 img 执行逆归一化操作
img = ((img * std) + mean)
img_array = img.numpy()
img_array = np.transpose(img_array, (1, 2, 0))
img_array = img_array[:, :, ::-1]
img_array = img_array * 255
img_array = img_array.astype(np.uint8)
cv2.imwrite(r"./class_imgs/Normalize.jpg", img_array)
程序运行结果如下:
<class 'torch.Tensor'>
Figure9:图像的高和宽分别是244*348