针对街道字符识别,利用Python和pytorch实现比赛中的数据读取和数据扩增。
from PIL import Image,ImageFilter
im = Image.open('E:\\yjs\\computer vision\\street recognition\\1.jpg' )
# im.show()
im2=im.filter(ImageFilter.BLUR)
im2.show()
from PIL import Image,ImageFilter
import cv2
import matplotlib.pyplot as plt
g = cv2.imread('E:\\yjs\\computer vision\\street recognition\\1.jpg' )
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #灰度图
plt.imshow(img)
#边缘检测
edges=cv2.Canny(img,30,70)
plt.imshow(edges)
plt.show()
结果:
OpenCv包含了众多的图像处理过功能,与图像相关的操作都可以在opencv中寻找。我们一般也是用opencv来读取图像。
原因:数据的数量和质量也可以决定模型效果的好坏,现在深度学习的参数很多,但是训练集的样本可能无法达到那么多。数据扩增可以增加训练集的样本空间,可以有效缓解过拟合的情况。给模型带来更大的泛化能力。
方法:从颜色空间、尺度空间到样本空间,同时根据不同任务数据扩增都有相应的区别。
对于图像分类,数据扩增一般不会改变标签;对于物体检测,数据扩增会改变物体坐标位置;对于图像分割,数据扩增会改变像素标签。
常见的数据扩增方法:在常见的数据扩增方法中,一般会从图像颜色、尺寸、形态、空间和像素等角度进行变换。当然不同的数据扩增方法可以自由进行组合,得到更加丰富的数据扩增方法。
以torchvision为例,常见的数据扩增方法包括:
transforms.CenterCrop 对图片中心进行裁剪
transforms.ColorJitter 对图像颜色的对比度、饱和度和零度进行变换
transforms.FiveCrop 对图像四个角和中心进行裁剪得到五分图像
transforms.Grayscale 对图像进行灰度变换
transforms.Pad 使用固定值进行像素填充
transforms.RandomAffine 随机仿射变换
transforms.RandomCrop 随机区域裁剪
transforms.RandomHorizontalFlip 随机水平翻转
transforms.RandomRotation 随机旋转
transforms.RandomVerticalFlip 随机垂直翻转
1.将数据读入Dataset,定制一个子类来继承Dataset。
class SVHNDataset(Dataset):
# SVHNDataset继承Dataset, 重载了__init__, __getitem__, __len__
# 实现将一个图片和图片对应的标签加载进入数据Dataset.
# 能够通过index索引数据集的数据,能够通过len,得到数据集大小
def __init__(self, img_path, img_label, transform=None):
self.img_path = img_path
self.img_label = img_label
if transform is not None:
self.transform = transform
else:
self.transform = None
# 得到数据集大小.
def __getitem__(self, index):
# 读取图片的过程,将图片转为一个tensor
# 读取图片
img = Image.open(self.img_path[index]).convert('RGB')
# 将图片进行增扩
if self.transform is not None:
# 在这个数据增扩过程当中,对我们的读入图片的数据转化成为了tensor.(使用transforms.ToTensor())
img = self.transform(img)
# 原始SVHN中类别10为数字0,# 设置最长的字符个数为5个。下面是标签字符的填充过程
lbl = np.array(self.img_label[index], dtype=np.int)
lbl = list(lbl) + (5 - len(lbl)) * [10]
return img, torch.from_numpy(np.array(lbl[:5]))
def __len__(self):
return len(self.img_path)
2.实例化这个类,加载我们真正的数据
# 读取训练的图片数据.
train_path = glob.glob('input/mchar_train/*.png')
train_path.sort()
# 读取训练图片的对应标签.
train_json = json.load(open('input/mchar_train.json'))
train_label = [train_json[x]['label'] for x in train_json]
# dataset理解成为一个仓库.加载了我们真正的数据集并利用torchvision的transform库进行数据增扩
dataset = SVHNDataset(train_path, train_label,
# compose将多个预处理步骤放在一起.,此处的数据增广是用了pytorch的官方数据增扩库torchvision.
transforms.Compose([
# 缩放到固定尺寸
transforms.Resize((64, 128)),
# 随机区域裁剪.
transforms.RandomCrop((60, 120)),
# 随机的颜色变换
transforms.ColorJitter(0.3, 0.3, 0.2),
# 加入一定的随机旋转
transforms.RandomRotation(5),
# 将图片转化为pytorch的tensor
transforms.ToTensor(),
# 将图片的像素进行归一化
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]))
3.利用DataLoader将Dataset中的数据集分批次读入。
data_loader=torch.utils.data.DataLoader(dataset,batch_size=10,shuffle=False,num_workers=0)
# data_loader将dataset中的数据以batch_size进行分组.保存在列表当中. data_loader[0] 就是前10个数据,每个数据包含了训练图片和图片标签
for data in data_loader:
# 前者为图像文件,batch*channel*height*width次序, 后面为字符标签.为batchsize*每个图像的标签个数.
print(data[0].size(),data[1].size())
#对每次批次提出来的数据进行处理()
break
## 输出 torch.Size([10, 3, 60, 120]) torch.Size([10, 5])
本博客内容来自DataWhale CV项目学习。