简单介绍
transform(transform.py)实际上是一个.py文件,其中含有各种类,能够实现各种功能。可以理解为一个工具箱,包含Compose、ToTensor、Resize等等各种工具,对transform的使用实际上就是:拿一些特定格式的图片(数据)(PIL、numpy等数据类型)经过(使用)transform中的工具,可以得到我们想要的结果
transform中结构
在PyCharm中进入transform的源代码,点击结果,查看transform中含有的类(方法)
内置函数:__call__()
__call__()方法,当实例化出类对象,并通过该实例化出的对象加参数形式,__call__会自动执行其中语句
代码示例:
class myclass():
def __init__(self):
self.lst = ['1', '2', '3']
def __call__(self, index):
return self.lst[index]
obj = myclass()
print(obj(1))
class myclass():
def __call__(self, name):
return f'hello {name}'
obj = myclass()
print(obj('PyTorch'))
常用的一些功能类
compose
结构
作用
将多个transform中的方法放入一个列表中,并在实例化Compose对象时传入,得到的对象可实现列表中的功能(执行顺序与列表中的顺序有关)
如代码中使用的,将Resize的实例化对象与ToTensor的实例化对象放入Compose的实例化对象参数中,使用Compose对象对图片进行处理,会先将PIL类型的图片变换尺寸,然后将得到尺寸变化的图片转换为Tensor数据类型
使用:写入日志文件
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('compose')
image_path = 'train/bees/205835650_e6f2614bee.jpg'
image = Image.open(image_path)
trans_Resize = transforms.Resize(1000)
trans_Tensor = transforms.ToTensor()
image_Tensor1 = trans_Tensor(image)
writer.add_image('compose', image_Tensor1, 1)
trans_Compose = transforms.Compose([trans_Resize, trans_Tensor])
image_Compose = trans_Compose(image)
writer.add_image('compose', image_Compose, 2)
writer.close()
compose处理前
compose处理后
ToTensor
该类的功能:把一个PIL的image或者numpy类型的image转换为一个Tensor数据类型的image(数据)
__call__()方法,给类对象传入pic(picture,一个PIL或者numpy数据类型的图片)自动调用,并返回一个Tensor数据类型的图片
PIL数据类型图片转换为Tensor数据类型
from torchvision import transforms
from PIL import Image
image_path = 'train/bees/17209602_fe5a5a746f.jpg'
image_PIL = Image.open(image_path)
trans_totensor = transforms.ToTensor() # 实例化类对象
trans_image = trans_totensor(image_PIL)
print(type(trans_image))
ToTensor的重要
将上述代码(图片类型转换)复制到Python控制台,查看trans_image中的属性
其中包括反向传播(神经网络中,根据结果,利用反向传播对前面过程中的参数进行一个调整),梯度、梯度方法
Tensor是神经网络专用的数据类型,因此,ToTensor是神经网络中一个重要的工具(包含神经网络所需的方法),在数据进入神经网络前先转换为Tensor类型,然后对其进行训练。
OpenCV
opencv:通过cv2.imread()读取到的图片数据类型为numpy.ndarray
Normlize
结构
作用
将图片标准化,图片3个维度的值在[0,1]之间,通过标准化图片可以将值转化为想要的区间内
使用
输入:实例化对象时__init__输入:均值(mean),标准差(std)
自动调用内置函数输入:tensor类型的图片
标准化:(img-mean)/std。此时图片将进行改变。
框外的公式中,input代表输入的数据的像素,mean代表均值,是实例化对象时传入的参数,std代表标准差,也是实例化对象时传入的参数、
根据方框内的公式,假设input(输入的图像数据)的像素的范围为[0, 1],那么result(输出的图像数据)的像素范围为[-1, 1]
from PIL import Image
from torchvision import transforms
image_path = 'train/bees/196430254_46bd129ae7.jpg'
image = Image.open(image_path)
trans_Tensor = transforms.ToTensor()
image_Tensor = trans_Tensor(image)
print(f'归一化前像素:{image_Tensor[0][0][0]}')
trans_Norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
image_Norm = trans_Norm(image_Tensor)
print(f'归一化后像素:{image_Norm[0][0][0]}')
套入公式:0.513... * 2 - 1 = 0.027 (约等于)
写入日志文件:对比前后变化
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('difference')
image_path = 'train/bees/196430254_46bd129ae7.jpg'
image = Image.open(image_path)
trans_Tensor = transforms.ToTensor()
image_Tensor = trans_Tensor(image)
writer.add_image('image', image_Tensor, 1)
print(f'归一化前像素:{image_Tensor[0][0][0]}')
trans_Norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
image_Norm = trans_Norm(image_Tensor)
print(f'归一化后像素:{image_Norm[0][0][0]}')
writer.add_image('image', image_Norm, 2)
writer.close()
Normlize(归一化前)的图片
经过Normlize后的图片
Resize
结构
作用
将PIL类型的图片重新变换尺寸,如200*200的图片尺寸,变为512*512(等比缩放)
使用
如果实例化Resize类对象时,传入的参数不是sequence序列而是一个int类型数,会对后续图像进行等比缩放
实例化对象输入:重新定义的尺寸大小(输入一般为( ,)类型,若为一个int型的值,如224,则表示把图像的短边统一为224,另外一边做同样倍速缩放,不一定为224)
调用内置函数输入:PIL类型的图片
输出:重新定义尺寸的图片
from torchvision import transforms
from PIL import Image
image_path = 'train/bees/205835650_e6f2614bee.jpg'
image = Image.open(image_path)
print(f'Resize处理前:{type(image)},{image.size}')
trans_Resize = transforms.Resize((512, 512))
image_Resize = trans_Resize(image)
print(f'Resize处理后:{type(image_Resize)},{image_Resize.size}')
处理前后图片的数据类型不变,处理之后图片尺寸变为实例化对象时传入的(512, 512)
写入日志文件:对比前后的变化
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('Resize')
image_path = 'train/bees/205835650_e6f2614bee.jpg'
image = Image.open(image_path)
trans_Tensor = transforms.ToTensor()
image_Tensor1 = trans_Tensor(image)
writer.add_image('Resize', image_Tensor1, 1)
print(f'Resize处理前:{type(image)},{image.size}')
trans_Resize = transforms.Resize((512, 512))
image_Resize = trans_Resize(image)
print(f'Resize处理后:{type(image_Resize)},{image_Resize.size}')
image_Tensor2 = trans_Tensor(image_Resize) # PIL -> Tensor
writer.add_image('Resize', image_Tensor2, 2)
writer.close()
Resize处理前
Resize处理后
RandomCrop
结构
功能
对图片进行随机尺度的裁剪,输入一个值,或者两个值(代表图片的宽,高),从图片的任意区域剪裁输入尺寸的图片
使用:写入日志文件比较前后变化
使用Compose与RandomCrop结合使用,并写入Tensorboard中
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('RandomCrop')
image_path = 'train/bees/132826773_dbbcb117b9.jpg'
image_PIL = Image.open(image_path)
trans_random = transforms.RandomCrop(100)
trans_Tensor = transforms.ToTensor()
trans_compose = transforms.Compose([trans_random, trans_Tensor])
for i in range(10): # 随机裁剪10张
image_Crop = trans_compose(image_PIL)
writer.add_image('RandomCrop', image_Crop, i)
writer.close()
注意:裁剪尺寸不得超出原始图片尺寸,否则将导致报错
裁剪结果:
练习:图形类型转换+Tensorboard展示
使用add_image()添加tensor类型的图像到日志文件中 通过tensorboard展示
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from PIL import Image
image_path = 'train/bees/17209602_fe5a5a746f.jpg'
image_PIL = Image.open(image_path)
trans_totensor = transforms.ToTensor() # 实例化类对象
trans_image = trans_totensor(image_PIL)
writer = SummaryWriter('ToTensor')
writer.add_image('ToTensor', trans_image)
writer.close()
总结
1、在使用前先要关注输入输出(需要输入的数据的数据类型、得到的输出的数据的数据类型)
2、多看官方文档
3、实例化对象时的所需参数、参数类型
4、不知道数据类型的时候、不知道返回值的时候,print或者print(type())或者debug或者查资料