pytorch数据加载和处理

scikit-image:用于图像的IO和变换

pandas:用于更容易地进行csv解析

读取csv中的数据

landmarks_frame = pd.read_csv('data/faces/face_landmarks.csv')

# 此处地址为存储csv文件的地址切记不可放置在C盘中,否则文件为只读无法进行读取和修改

读取到的注释信息做一定的处理,一般第一列为图像名字,后面的列为图像中注释的具体信息

n = 65

# n 为特征点的数量

img_name = landmarks_frame.iloc[n, 0] 

# 读取第一列信息,若只需读取某一个图片,具体索引即可

landmarks = landmarks_frame.iloc[n, 1:].as_matrix()

#  以矩阵形式输出注释信息

landmarks = landmarks.astype('float').reshape(-1, 2)

# 对注释信息的数据类型,shape修改为想要

print('Image name: {}'.format(img_name))

print('Landmarks shape: {}'.format(landmarks.shape))

print('First 4 Landmarks: {}'.format(landmarks[:4]))

编写函数展示图片和它对应的标注点为例子

def show_landmarks(image, landmarks):

"""显示带有地标的图片"""

plt.imshow(image)

# 用于显示图像,可以传递一个二维或者三维的数组作为参数,将图像数据显示为图形

plt.scatter(landmarks[:, 0], landmarks[:, 1], s=10, marker='.', c='r')

# 生成散点图PYthon——plt.scatter各参数详解_plt.scatter()函数参数-CSDN博客

plt.pause(0.001)

 # pause a bit so that plots are updated

plt.figure()

show_landmarks(io.imread(os.path.join('data/faces/', img_name)),

landmarks)

plt.show()

数据集类

自定义数据集应继承Dataset并覆盖以下方法*_ _len_ _实现len(dataset)返还数据集的尺寸。

*_ _getitem_ _用来获取一些索引数据

建立数据集类

假设为面部数据创建一个数据集类,_ _init_ _中读取csv的文件内容,再_ _getitem_ _中读取数据图片,在需要图片时才读取,可以有限节省内存空间。

收集面部特征时数据样本按一个字典{‘image’:image,‘landmarks’:landmarks}组织

此时数据集类添加了一个可选参数transform以方便对样本预处理

class FaceLandmarksDataset(Dataset):

"""面部标记数据集."""

def __init__(self, csv_file, root_dir, transform=None):

csv_file(string)

# 带注释的csv文件的路径,string表示输入的字符串

root_dir string)

# 包含所有图像的目录

transform(callable, optional)

# 一个样本上的可用的可选变换

self.landmarks_frame = pd.read_csv(csv_file)

#  读取csv文件中的内容

self.root_dir = root_dir

# 读取图像的目录

self.transform = transform

 

def __len__(self):

return len(self.landmarks_frame)

# 返还数据集的尺寸

def __getitem__(self, idx):

img_name = os.path.join(self.root_dir,self.landmarks_frame.iloc[idx, 0])

# 拼接文件路径os.path.join()函数用法详解-CSDN博客

image = io.imread(img_name)

landmarks = self.landmarks_frame.iloc[idx, 1:]

landmarks = np.array([landmarks])

landmarks = landmarks.astype('float').reshape(-1, 2)

sample = {'image': image, 'landmarks': landmarks}

if self.transform:

sample = self.transform(sample)

return sample

数据可视化

实例化这个类并遍历数据样本

face_dataset = FaceLandmarksDataset(csv_file='data/faces/face_landmarks.csv',

root_dir='data/faces/')

# 加载数据集

fig = plt.figure()

for i in range(len(face_dataset)):

sample = face_dataset[i]

print(i, sample['image'].shape, sample['landmarks'].shape)

ax = plt.subplot(1, 4, i + 1)

plt.tight_layout()

ax.set_title('Sample #{}'.format(i))

ax.axis('off')

show_landmarks(**sample)

 

if i == 3:

plt.show()

break

数据变换

图片尺寸转换三个转换:

Rescale 缩放图片

Randomcrap 对图片进行随机裁剪

Totensor 把numpy格式转换为torch

使用_ _call_ _方法,写成调用的类的形式,而不是简单的函数,在每次调用的时候就不要传递参数,使用_ _call_ _的方法就可以实现调用。

 

class Rescale(object):

"""将样本中的图像重新缩放到给定大小。.

Args:

output_size(tuple或int):所需的输出大小。 如果是元组,则输出为

与output_size匹配。 如果是int,则匹配较小的图像边缘到output_size保持纵横比相同。

"""

def __init__(self, output_size):

assert isinstance(output_size, (int, tuple))

#assert 插入调试断点,当出现不等的情况时程序中断

# isinstance判断变量是否为某个类型

# 在此例子中为判断输出的是否为int或i者元组型,不是的话返回False,assert检测到false中断程序运行,是的话返回true程序继续运行

self.output_size = output_size

 

def __call__(self, sample):

# _ _call_ _函数

image, landmarks = sample['image'], sample['landmarks']

h, w = image.shape[:2]

# 将图像的尺寸赋值给参数h和w

if isinstance(self.output_size, int):

if h > w:

new_h, new_w = self.output_size * h / w, self.output_size

else:

new_h, new_w = self.output_size, self.output_size * w / h

else:

new_h, new_w = self.output_size

new_h, new_w = int(new_h), int(new_w)

img = transform.resize(image, (new_h, new_w))

# 对输入图像的尺寸进行处理,不满足尺寸的情况进行处理

# h and w are swapped for landmarks because for images,

# x and y axes are axis 1 and 0 respectively

landmarks = landmarks * [new_w / w, new_h / h]

return {'image': img, 'landmarks': landmarks}

 

class RandomCrop(object):

"""随机裁剪样本中的图像.

Args:

output_size(tuple或int):所需的输出大小。 如果是int,方形裁剪是。

方形裁剪"

def __init__(self, output_size):

assert isinstance(output_size, (int, tuple))

if isinstance(output_size, int):

self.output_size = (output_size, output_size)

else:

assert len(output_size) == 2

self.output_size = output_size

def __call__(self, sample):

image, landmarks = sample['image'], sample['landmarks']

h, w = image.shape[:2]

new_h, new_w = self.output_size

top = np.random.randint(0, h - new_h)

# 生成随机整数

left = np.random.randint(0, w - new_w)

image = image[top: top + new_h,left: left + new_w]

landmarks = landmarks - [left, top]

return {'image': image, 'landmarks': landmarks}

class ToTensor(object):

"""将样本中的ndarrays转换为Tensors."""

def __call__(self, sample):

image, landmarks = sample['image'], sample['landmarks']

# 交换颜色轴因为

# numpy包的图片是: H * W * C

# torch包的图片是: C * H * W

image = image.transpose((2, 0, 1))

# transpose函数:opencv读入图片的矩阵为(height,width,channels)

torch的需要的是(channels,height,width)

所以进行转换变为2.0.1

return {'image': torch.from_numpy(image),'landmarks': torch.from_numpy(landmarks)}

组合变换

示例:我们想要把图像的短边调整为256,然后随机裁剪(randomcrop) 为224大小的正方形。也就是说,我们打算组合一个Rescale 和 RandomCrop 的变换。

具体实现

scale = Rescale(256)

# 调用Rescale函数

crop = RandomCrop(128)

# 调用RandomCrop函数

composed = transforms.Compose([Rescale(256),RandomCrop(224)])

# transforms.Compose将多个数据变换组合在一起,以便将他们应用于数据

# 在样本上应用上述的每个变换

fig = plt.figure()

sample = face_dataset[65]

for i, tsfrm in enumerate([scale, crop, composed]):

# enumerate(iteration, start)函数默认包含两个参数,其中iteration参数为需要遍历的参数,比如字典、列表、元组等,start参数为开始的参数,默认为0(不写start那就是从0开始)

 

transformed_sample = tsfrm(sample)

ax = plt.subplot(1, 3, i + 1)

# 将数据划分为几块区域

# subplot(M,N,P)是将多个图画到一个平面上的工具。其中,m表示是图排成m行,n表示图排成n列,也就是整个figure中有n个图是排成一行的,一共m行,如果m=2就是表示2行图。p表示图所在的位置,p=1表示从左到右从上到下的第一个位置。

plt.tight_layout()

ax.set_title(type(tsfrm).__name__)

show_landmarks(**transformed_sample)

plt.show()

迭代数据集

将上述组合起来创建一个带组合转换的数据集

每次这个数据集被采样时: *及时地从文件中读取图片 * 对读取的图片应用转换 * 由于其中一步操作是随机的 (randomcrop) , 数据被增强了

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用PyTorch进行处理数据的一般步骤如下: 1. 导入必要的PyTorch模块,例如`torch`、`torchvision`等。 2. 准备数据集。PyTorch支持多种数据集格式,包括自定义数据集、ImageNet、CIFAR等常见数据集。您可以使用`torchvision.datasets`模块中的`ImageFolder`、`CIFAR10`等类,或编写自己的数据集类。 3. 使用`transforms`模块对数据进行预处理。`transforms`模块提供了多种数据处理方法,例如缩放、裁剪、旋转、归一化等。您可以使用`transforms.Compose`将多个预处理方法组合起来。 4. 使用`DataLoader`数据。`DataLoader`可以将数据集按照batch size划分为多个小批量,并提供多线程数据数据打乱等功能。 下面是一个简单的例子,假设您要CIFAR10数据集: ```python import torch import torchvision import torchvision.transforms as transforms # 定义预处理方法 transform = transforms.Compose( [transforms.Resize((32, 32)), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) # 数据集 trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, num_workers=2) testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False, num_workers=2) ``` 在这个例子中,我们使用了`transforms.Resize`将图像缩放到32x32大小,使用`transforms.ToTensor`将图像转换为PyTorch张量格式,使用`transforms.Normalize`对图像进行归一化处理。然后使用`torchvision.datasets.CIFAR10`CIFAR10数据集,并使用`torch.utils.data.DataLoader`将数据集划分为小批量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值