赞
踩
物体检测和数据集
目标检测和图片分类的区别
图片分类:
目标检测:
目标检测相对于图片分类来讲所做的工作更多,它需要找出所有感兴趣的物体,当图片中只有一个物体时,可以将目标检测看成是图像分类,把图像中最主要的物体当作是图片的类别,但是当图片中有多个物体的时候,目标检测不仅能将所有的物体都检测出来,还能将他们所在的位置标注出来,所以目标检测的应用场景相对来讲更多
目标检测的应用
边缘框(boundingbox)
边缘框可以用四个数字来定义(两种常用的表示方法)
正方向
目标检测数据集
COCO数据集
数据集的读取
读取小批量的时候,图像的小批量的形状为(批量大小、通道数、高度、宽度),与图像分类任务中的相同
标签的小批量的形状为(批量大小,m,5)
小批量计算虽然高效,但是要求每张图像含有相同数量的边界框,以便放在同一个批量中
总结
代码:
- %matplotlib inline
- import torch
- from d2l import torch as d2l
-
- d2l.set_figsize()
- img = d2l.plt.imread('01_Data/1664187097901.jpg')
- d2l.plt.imshow(img)
-
- # 定义在这两种表示之间进行转换的函数
- def box_corner_to_center(boxes):
- """从(左上,右下)转换到(中间,宽度,高度)"""
- x1, y1, x2, y2 = boxes[:,0], boxes[:,1], boxes[:,2], boxes[:,3]
- cx = (x1 + x2) / 2
- cy = (y1 + y2) / 2
- w = x2 - x1
- h = y2 - y1
- boxes = torch.stack((cx,cy,w,h),axis = -1)
- return boxes
-
- def box_center_to_corner(boxes):
- """从(中间,宽度,高度)转换到(左上,右下)"""
- cx, cy, w, h = boxes[:,0], boxes[:,1], boxes[:,2], boxes[:,3]
- x1 = cx - 0.5 * w
- y1 = cy - 0.5 * h
- x2 = cx + 0.5 * w
- y2 = cy + 0.5 * h
- boxes = torch.stack((x1,y1,x2,y2),axis = -1)
- return boxes
-
- dog_bbox, cat_bbox = [60.0, 45.0, 378.0, 516.0], [400.0, 112.0, 655.0, 493.0]
- boxes = torch.tensor((dog_bbox,cat_bbox))
- # boxes 转中间表示,再转回来,等于自己
- box_center_to_corner(box_corner_to_center(boxes)) == boxes
-
- # 将边界框在图中画出
- def bbox_to_rect(bbox,color):
- return d2l.plt.Rectangle(xy=(bbox[0],bbox[1]),width=bbox[2]-bbox[0],
- height=bbox[3] - bbox[1], fill=False,
- edgecolor=color,linewidth=2)
-
- fig = d2l.plt.imshow(img)
- fig.axes.add_patch(bbox_to_rect(dog_bbox,'blue'))
- fig.axes.add_patch(bbox_to_rect(cat_bbox,'red'))
目标检测数据集代码:
- %matplotlib inline
- import os
- import pandas as pd
- import torch
- import torchvision
- from d2l import torch as d2l
-
- d2l.DATA_HUB['banana-detection'] = (d2l.DATA_URL + 'banana-detection.zip','5de25c8fce5ccdea9f91267273465dc968d20d72')
-
- # 读取香蕉检测数据集
- def read_data_bananas(is_train=True):
- """读取香蕉检测数据集中的图像和标签"""
- data_dir = d2l.download_extract('banana-detection')
- csv_fname = os.path.join(data_dir,
- 'bananas_train' if is_train else 'bananas_val',
- 'label.csv')
- csv_data = pd.read_csv(csv_fname)
- csv_data = csv_data.set_index('img_name')
- images, targets = [], []
- # 把图片、标号全部读到内存里面
- for img_name, target in csv_data.iterrows():
- images.append(torchvision.io.read_image(os.path.join(data_dir,'bananas_train' if is_train else 'bananas_val',
- 'images',f'{img_name}')))
- targets.append(list(target))
- print("len(targets):",len(targets))
- print("len(targets[0]):",len(targets[0]))
- print("targets[0][0]....targets[0][4]:",targets[0][0], targets[0][1], targets[0][2], targets[0][3], targets[0][4])
- print("type(targets):",type(targets))
- print("torch.tensor(targets).unsqueeze(1).shape:",torch.tensor(targets).unsqueeze(1).shape) # unsqueeze函数在指定位置加上维数为一的维度
- print("len(torch.tensor(targets).unsqueeze(1) / 256):", len(torch.tensor(targets).unsqueeze(1) / 256))
- print("type(torch.tensor(targets).unsqueeze(1) / 256):", type(torch.tensor(targets).unsqueeze(1) / 256))
- return images, torch.tensor(targets).unsqueeze(1) / 256 # 归一化使得收敛更快
-
- # 创建一个自定义Dataset实例
- class BananasDataset(torch.utils.data.Dataset):
- """一个用于加载香蕉检测数据集的自定义数据集"""
- def __init__(self, is_train):
- self.features, self.labels = read_data_bananas(is_train)
- print('read ' + str(len(self.features)) + (f' training examples' if is_train else f'validation examples'))
-
- def __getitem__(self, idx):
- return (self.features[idx].float(), self.labels[idx])
-
- def __len__(self):
- return len(self.features)
-
- # 为训练集和测试集返回两个数据加载器实例
- def load_data_bananas(batch_size):
- """加载香蕉检测数据集"""
- train_iter = torch.utils.data.DataLoader(BananasDataset(is_train=True),
- batch_size, shuffle=True)
- val_iter = torch.utils.data.DataLoader(BananasDataset(is_train=False),
- batch_size)
- return train_iter, val_iter
-
-
- # 读取一个小批量,并打印其中的图像和标签的形状
- batch_size, edge_size = 32, 256
- train_iter, _ = load_data_bananas(batch_size)
- batch = next(iter(train_iter))
- # ([32,1,5]) 中的1是每张图片中有几种类别,这里只有一种香蕉要识别的类别
- # 5是类别标号、框的四个参数
- batch[0].shape, batch[1].shape
-
-
- # 示例
- # pytorch里permute是改变参数维度的函数,
- # Dataset里读的img维度是[batch_size, RGB, h, w],
- # 但是plt画图的时候要求是[h, w, RGB],所以要调整一下
-
- # 做图片的时候,一般是会用一个ToTensor()将图片归一化到【0, 1】,这样收敛更快
- print("原始图片:\n", batch[0][0])
- print("原始图片:\n", (batch[0][0:10].permute(0,2,3,1)))
- print("归一化后图片:\n", (batch[0][0:10].permute(0,2,3,1)) / 255 )
- imgs = (batch[0][0:10].permute(0,2,3,1)) / 255
- #imgs = (batch[0][0:10].permute(0,2,3,1))
- # d2l.show_images输入的imgs图片参数是归一化后的图片
- axes = d2l.show_images(imgs, 2, 5, scale=2)
- for ax, label in zip(axes, batch[1][0:10]):
- d2l.show_bboxes(ax, [label[0][1:5] * edge_size], colors=['w'])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。