零基础入门CV赛事—Task 2 数据读取与数据扩增

本文介绍了计算机视觉比赛中数据读取和扩增的重要性。讲解了如何使用Pillow和OpenCV进行图像读取,并探讨了数据扩增在深度学习中的作用,列举了一些常见的数据扩增方法,以及在PyTorch中如何实现数据读取和扩增。通过DataLoder批量读取数据,提高了训练效率。
部署运行你感兴趣的模型镜像

上篇说明了赛题的内容和三种解题方法:定长字符识别,不定长字符识别和检测再识别。从本章开始我们将逐渐的学习使用【定长字符识别】思路来构建模型,逐步讲解赛题的解决方案和相应知识点。

数据读取与数据扩增

1.1 学习目标

  • 学习Python和Pytorch中图像读取
  • 学会扩增方法和Pytorch读取赛题数据

1.2图像读取

由于赛题数据是图像数据,赛题的任务是识别图像中的字符。因此我们首先需要完成对数据的读取操作,在Python中有很多库可以完成数据读取的操作,比较常见的有Pillow和OpenCV。

1.2.1 Pillow

Pillow (PIL Fork)

Pillow是Python图像处理函式库(PIL)的一个分支。Pillow提供了常见的图像读取和处理的操作,而且可以与ipython notebook无缝集成,是应用比较广泛的库。

# 导入Pillow库 
from PIL import Image, ImageFilter
#读取图片
im = Image.open('cat.jpg')
# 应用模糊滤镜:
im2 = im.filter(ImageFilter.BLUR)
#更改图片尺寸(缩放)
im.thumbnail((w//2, h//2))
#顺时针旋转90°
im.rotate(45)
#保存图片
im2.save('blur.jpg', 'jpeg')

以上是pillow的基础操作

1.2.2 opencv

OpenCV在功能上比Pillow更加强大很多,学习成本也高很多。OpenCV包含了众多的图像处理的功能,OpenCV包含了你能想得到的只要与图像相关的操作。此外OpenCV还内置了很多的图像特征处理算法,如关键点检测、边缘检测和直线检测等。

# 导入Opencv库
import cv2
#读取图片
img = cv2.imread('cat.jpg')
# 转换为灰度图
img =cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#弹出标题名为"转化成灰度"的窗口,显示图片
imshow("转化成灰度", img);
# Canny边缘检测
edges = cv2.Canny(img, 30, 70)
#保持图片
cv2.imwrite('canny.jpg', edges)

详细请见opencv中文网站

1.3数据扩增

  • 在赛题中我们需要对的图像进行字符识别,因此需要我们完成的数据的读取操作,同时也需要完成数据扩增(Data
    Augmentation)操作。在深度学习中数据扩增方法非常重要,数据扩增可以增加训练集的样本,同时也可以有效缓解模型过拟合的情况,也可以给模型带来的更强的泛化能力。
  • 数据扩增方法有很多:从颜色空间、尺度空间到样本空间,同时根据不同任务数据扩增都有相应的区别。
  • 对于图像分类,数据扩增一般不会改变标签;对于物体检测,数据扩增会改变物体坐标位置;对于图像分割,数据扩增会改变像素标签。

1.3.1常见的数据扩增方法、

以torchvision为例,常见的数据扩增方法包括:
PyTorch中文文档

方法功能
transforms.CenterCrop对图片中心进行裁剪
transforms.ColorJitter对图像颜色的对比度、饱和度和零度进行变换
transforms.FiveCrop对图像四个角和中心进行裁剪得到五分图像
transforms.Grayscale对图像进行灰度变换
transforms.RandomHorizontalFlip随机水平翻转
transforms.RandomRotation随机旋转
transforms.RandomVerticalFlip随机垂直翻转

1.3.2 pytorch读取数据

import os, sys, glob, shutil, json
import cv2

from PIL import Image
import numpy as np

import torch
from torch.utils.data.dataset import Dataset
import torchvision.transforms as transforms

class SVHNDataset(Dataset):
    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):
        img = Image.open(self.img_path[index]).convert('RGB')

        if self.transform is not None:
            img = self.transform(img)
        
        # 原始SVHN中类别10为数字0
        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)

train_path = glob.glob('../input/train/*.png')
train_path.sort()
train_json = json.load(open('../input/train.json'))
train_label = [train_json[x]['label'] for x in train_json]

data = SVHNDataset(train_path, train_label,
          transforms.Compose([
              # 缩放到固定尺寸
              transforms.Resize((64, 128)),

              # 随机颜色变换
              transforms.ColorJitter(0.2, 0.2, 0.2),

              # 加入随机旋转
              transforms.RandomRotation(5),

              # 将图片转换为pytorch 的tesntor
              # transforms.ToTensor(),

              # 对图像像素进行归一化
              # transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])
            ]))

上述代码可以在读取过程中的进行数据扩增,将一张图片阔增为三张
接下来我们将在定义好的Dataset基础上构建DataLoder,你可以会问有了Dataset为什么还要有DataLoder?其实这两个是两个不同的概念,是为了实现不同的功能。

  • Dataset:对数据集的封装,提供索引方式的对数据样本进行读取
  • DataLoder:对Dataset进行封装,提供批量读取的迭代读取
    加入DataLoder后,数据读取代码改为如下:
import os, sys, glob, shutil, json
import cv2

from PIL import Image
import numpy as np

import torch
from torch.utils.data.dataset import Dataset
import torchvision.transforms as transforms

class SVHNDataset(Dataset):
    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):
        img = Image.open(self.img_path[index]).convert('RGB')

        if self.transform is not None:
            img = self.transform(img)
        
        # 原始SVHN中类别10为数字0
        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)

train_path = glob.glob('../input/train/*.png')
train_path.sort()
train_json = json.load(open('../input/train.json'))
train_label = [train_json[x]['label'] for x in train_json]

train_loader = torch.utils.data.DataLoader(
        SVHNDataset(train_path, train_label,
                   transforms.Compose([
                       transforms.Resize((64, 128)),
                       transforms.ColorJitter(0.3, 0.3, 0.2),
                       transforms.RandomRotation(5),
                       transforms.ToTensor(),
                       transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
            ])), 
    batch_size=10, # 每批样本个数
    shuffle=False, # 是否打乱顺序
    num_workers=10, # 读取的线程个数
)

for data in train_loader:
    break

在加入DataLoder后,数据按照批次获取,每批次调用Dataset读取单个样本进行拼接。此时data的格式为:
torch.Size([10, 3, 64, 128]), torch.Size([10, 6])
前者为图像文件,为batchsize * chanel * height * width次序;后者为字符标签。

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值