下文中有使用到plt,不懂的可看我这篇文章:
python之Matplotlib详细分析(附代码)
数据比较少的时候使用数据增强是一个不错的选择
导入对应的包:
from PIL import Image
from torchvision import transforms as tfs
读取对应的照片:
image = Image.open('scenery.jpg')
print(image.size)
image
截图如下:
数据增强的处理方式有如下
裁剪之前 先叙述一遍缩放(毕竟裁剪是基于缩放的基础)
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.Resize((300,300))(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1, 2)
axs[0].set_title('474 * 379')
axs[0].imshow(img)
axs[1].set_title('300 * 300')
axs[1].imshow(img1)
截图如下:
- 核心函数:
transforms.CenterCrop(size)
size 参数为int,将其原图 中心裁剪为设定尺寸
如果参数为(h,w),则裁剪的尺寸为(h,w)
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.CenterCrop(300)(img)
img2 = tfs.CenterCrop((300,200))(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1, 2)
axs[0].set_title('300 * 300')
axs[0].imshow(img1)
axs[1].set_title('300 * 200')
axs[1].imshow(img2)
截图如下:
- 核心函数:
transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant')
参数 | 具体说明 |
---|
size | 1.为size,结果为size * size 2.为(h,w),结果为h * w |
padding | 填充大小 1.为a,上下左右填充a 2.为(a,b)时,左右填充a个像素,上下填充b个像素 3.为(a,b,c,d)时,左、上、右、下分别填充a、b、c、d |
pad_if_need | 默认为False 为True,超出尺寸进行填充 |
fill | 通道填充的颜色 |
padding_mode | 填充模式 1.constant,像素值由fill填充 2.edge,图像边缘像素值填充 3.reflect,镜像填充,最后一个像素不镜像,也就是反射。1, 2, 3, 4 变为 3, 2, 1, 2, 3, 4, 3, 2 4.symmetric,镜像填充,最后一个像素镜像,也就是对称。1, 2, 3, 4 变为 2, 1, 1, 2, 3, 4, 4, 3 |
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomCrop(300)(img)
img2 = tfs.RandomCrop(300,padding=(16, 64))(img)
img3 = tfs.RandomCrop(300,padding=(16, 64),fill=(255, 255, 0))(img)
img4 = tfs.RandomCrop(2000,pad_if_needed=True)(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,4)
axs[0].set_title('img1')
axs[0].imshow(img1)
axs[1].set_title('img2')
axs[1].imshow(img2)
axs[2].set_title('img3')
axs[2].imshow(img3)
axs[3].set_title('img4')
axs[3].imshow(img4)
截图如下:
按照填充模式的代码:
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomCrop(500,padding=128,padding_mode='constant')(img)
img2 = tfs.RandomCrop(500,padding=128,padding_mode='edge')(img)
img3 = tfs.RandomCrop(500,padding=128,padding_mode='reflect')(img)
img4 = tfs.RandomCrop(500,padding=128,padding_mode='symmetric')(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,4)
axs[0].set_title('img1')
axs[0].imshow(img1)
axs[1].set_title('img2')
axs[1].imshow(img2)
axs[2].set_title('img3')
axs[2].imshow(img3)
axs[3].set_title('img4')
axs[3].imshow(img4)
截图如下:
- 核心函数:
transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(3/4, 4/3), interpolation=<InterpolationMode.BILINEAR: 'bilinear'>)
参数 | 具体说明 |
---|
size | 1.为size,结果为size * size 2.为(h,w),结果为h * w |
scale | 随机裁剪面积比例,默认区间(0.08,1)之间随机取一个数 |
ratio | 随机长宽比,默认区间(3/4,4/3)之间随机取一个数 |
interpolation | 插值方法(PIL. Image. NEAREST , PIL. Image. BILINEAR , PIL. Image. BICUBIC ) |
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomResizedCrop(300,scale=(0.1,1))(img)
img2 = tfs.RandomResizedCrop(300,ratio=(1,4/3))(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,3)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('img1')
axs[1].imshow(img1)
axs[2].set_title('img2')
axs[2].imshow(img2)
截图如下:
- 核心函数:
transforms.RandomHorizontalFlip(p=0.5)
p为概率值,如果p为1,百分百翻转。p为0.5 ,百分之50的概率可能会翻转也可能不会
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomHorizontalFlip(p=1)(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1, 2)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('flip horizontal')
axs[1].imshow(img1)
截图如下:
- 核心函数:
transforms.RandomVerticalFlip(p=0.5)
p为概率值,如果p为1,百分百翻转。p为0.5 ,百分之50的概率可能会翻转也可能不会
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomVerticalFlip(p=1)(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1, 2)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('flip vertical')
axs[1].imshow(img1)
截图如下:
- 核心函数:
transforms.RandomRotation(degrees, expand=False, center=None, fill=0, resample=None)
参数 | 具体说明 |
---|
degrees | 旋转角度 1.为a,在(-a,a)区间随机选择旋转角度 2.为(a,b),在在(a,b)区间随机选择旋转角度 |
expand | 图片超出尺寸是否显示完整图 1.默认False,超出不会显示完整图 2.True,超出会显示完整图 |
center | 旋转轴位置 默认中心旋转 |
resample | 重采样方法 |
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomRotation(degrees=(45, 45))(img)
img2 = tfs.RandomRotation(degrees=(45, 45), expand=True)(img)
img3 = tfs.RandomRotation(degrees=(45, 45), fill=(255, 255, 0))(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,4)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('img1')
axs[1].imshow(img1)
axs[2].set_title('img2')
axs[2].imshow(img2)
axs[3].set_title('img3')
axs[3].imshow(img3)
截图如下:
- 核心函数:
transforms.Grayscale(num_output_channels=1)
一般不设置,默认单通道灰度,如果需要三通道灰度,则对应将其值改为3即可
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.Grayscale()(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,2)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('gray')
axs[1].imshow(img1)
截图如下:
- 核心函数:
transforms.ColorJitter(brightness=0, contrast=0, saturation=0, hue=0)
参数 | 具体说明 |
---|
brightness | 亮度 1.元组(min, max),给定区间随机变换,不可有负值 2.浮点数,亮度范围为[max(0, 1 - brightness), 1 + brightness] |
contrast | 对比度。规则同上 |
saturation | 饱和度。规则同上 |
hue | 色调 1.元组(min, max),给定区间随机变换,不可有负值 2.浮点数,色调范围为[-hue, hue]区间随机变换 整体区间范围为[0,0.5] or [-0.5,0.5] |
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.ColorJitter(brightness=(3, 3))(img)
img2 = tfs.ColorJitter(contrast=(3, 3))(img)
img3 = tfs.ColorJitter(saturation=(3, 3))(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,4)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('brightness')
axs[1].imshow(img1)
axs[2].set_title('contrast')
axs[2].imshow(img2)
axs[3].set_title('saturation')
axs[3].imshow(img3)
截图如下:
- 核心函数:
transforms.RandomInvert(p=0.5)
p为概率值,如果p为1,百分百翻转。p为0.5 ,百分之50的概率可能会翻转也可能不会
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomInvert(p=0.5)(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,2)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('img1')
axs[1].imshow(img1)
截图如下:
- 核心函数:
transforms.RandomAdjustSharpness(sharpness_factor, p=0.5)
sharpness_factor 该参数为调整锐度,0为模糊,1为原图。随着数字越大,锐度越高,没有设置锐度上限
p为概率值,如果p为1,百分百翻转。p为0.5 ,百分之50的概率可能会翻转也可能不会
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomAdjustSharpness(200)(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,2)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('img1')
axs[1].imshow(img1)
截图如下:
- 核心函数:
transforms.GaussianBlur(kernel_size, sigma=(0.1, 2.0))
参数 | 具体说明 |
---|
kernel_size | 模糊半径(奇数) |
sigma | 正态分布标准差 1.为(min, max),在(min, max)区间随机取一个数 2.浮点数,则为该数 |
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.GaussianBlur(11,10)(img)
img2 = tfs.GaussianBlur(51,10)(img)
img3 = tfs.GaussianBlur(101,100)(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,4)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('img1')
axs[1].imshow(img1)
axs[2].set_title('img2')
axs[2].imshow(img2)
axs[3].set_title('img3')
axs[3].imshow(img3)
截图如下:
- 核心函数:
transforms.Pad(padding, fill=0, padding_mode=‘constant’)
参数 | 具体说明 |
---|
padding | 拓展大小 1.为a,上下左右填充a 2.为(a,b)时,左右填充a个像素,上下填充b个像素 3.为(a,b,c,d)时,左、上、右、下分别填充a、b、c、d |
fill | 填充值 默认0,黑色。也可填充三通道 |
padding_mode | 填充模式 1.constant,像素值由fill填充 2.edge,图像边缘像素值填充 3.reflect,镜像填充,最后一个像素不镜像,也就是反射。1, 2, 3, 4 变为 3, 2, 1, 2, 3, 4, 3, 2 4.symmetric,镜像填充,最后一个像素镜像,也就是对称。1, 2, 3, 4 变为 2, 1, 1, 2, 3, 4, 4, 3 |
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.Pad(100,fill=(0, 0, 255))(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,2)
axs[0].set_title('original')
axs[0].imshow(img)
axs[1].set_title('img1')
axs[1].imshow(img1)
截图如下:
该含义为:旋转、平移、缩放、扭曲等组合
- 核心函数:
transforms.RandomAffine(degrees, translate=None, scale=None, shear=None, resample=0, fillcolor=0)
参数 | 具体说明 |
---|
degrees | 随机旋转角度范围,0为不旋转 |
translate | 水平和垂直平移因子 为(a, b),水平平移位置为 (-img_width * a , img_width * a)该区间随机选择一个数。垂直平移为 (-img_height * b , img_height * b)该区间随机选择一个数 |
scale | 缩放因子 为(a, b),在(a, b)区间随机选择一个数 |
shear | 随机扭曲角度范围 为(a, b),在(a, b)区间随机选择一个数 |
resample | 重采样 |
fillcolor | 填充色彩,可三通道填充 |
from PIL import Image
from torchvision import transforms as tfs
img = Image.open('scenery.jpg')
img1 = tfs.RandomAffine(45)(img)
img2 = tfs.RandomAffine(0, (0.7, 0))(img)
img3 = tfs.RandomAffine(0, None, (3, 5))(img)
img4 = tfs.RandomAffine(0, None, None, (45, 90))(img)
import matplotlib.pyplot as plt
axs = plt.figure().subplots(1,4)
axs[0].set_title('img1')
axs[0].imshow(img1)
axs[1].set_title('img2')
axs[1].imshow(img2)
axs[2].set_title('img3')
axs[2].imshow(img3)
axs[3].set_title('img4')
axs[3].imshow(img4)
截图如下:
对应详解博客为<< Pytorch框架学习路径(九:transforms图像增强(一))>>的链接为https://blog.csdn.net/weixin_54546190/article/details/125126358?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22125126358%22%2C%22source%22%3A%22weixin_54546190%22%7D&ctrtid=hsqhW。博客中会有永久的本人录制的代码讲解视频百度网盘链接。
卷积神经网络非常容易出现过拟合的问题,而数据增强的方法是对抗过拟合问题的一个重要方法。
2012 年 AlexNet 在 ImageNet 上大获全胜,图片增强方法功不可没,因为有了图片增强,使得训练的数据集比实际数据集多了很多’新’样本,减少了过拟合的问题,下面我们来具体解释一下。
常用的数据增强方法
常用的数据增强方法如下:
1.对图片进行一定比例缩放
2.对图片进行随机位置的截取
size:依据给定size随机剪裁。如果是一个数a,就是(a,a);如果是两个数就是(h,w)
二、随机剪裁
class torchvision.transforms.RandomCrop(size,padding=None,pad_if_need=False,fill=0,padding_mode='constant')
参数解释:
size:依据给定size随机剪裁。如果是一个数a,
(1) torchvision.tramsforms__可以用于图像预处理和数据增强(数据缩放、翻转等)
(2)torchvision.datasets__包括一些常见数据集(Fashion-MNIST、ImageNet、VOC等)
(3)torchvision.models__包括一些官方预训练模型权重(VGG、ResNet、Mobilenetv2等)
(4)torchvision.utils__提供一些可视化方法
在图像裁剪操作中,opencv和pillow两个库都具有相应的函数,但是这两个库中的函数仅仅能对与图片平行的矩形进行裁剪操作,如果想要对目标的最小外接矩形进行裁剪该如何操作呢?如下所示:
具体处理该问题的思路如下:
计算最小外接矩形的四个点的坐标,旋转角度
将原图像进行旋转,旋转角度为最小外接矩形的角度
将四个点的坐标进行映射,求出被旋转后图像的四个点的坐标
利用这四个点对图像进行裁剪
图像原图如下:
1 求出该区域的最小外接矩形,并且得到外接矩形的四个点的坐标和旋转角度。
rect = cv2.minAreaRect(self.contours[0])#rect为[(旋转中心x坐
1)变换的组合,要想将多个变换组合在一起,请使用Compose
2)在中心剪裁给定的图像CenterCrop(size),
3)随机更改图像的亮度、对比度、饱和度和色度ColorJitter(brightness=0, contrast=0, saturation=0, hue=0),参数为浮点数或者tuple,例如0.5表示(0.5,1.5)的改变
4)以给定的概率随机水平翻转给定的图像RandomHo.