当前位置: 首页 > news >正文

如何使用COCO数据集,注意事项

COCO数据集可用来训练目标检测,分类,实例分割等。

下面简单说下如何使用这个数据集,
数据集下载可用如下的代码进行,以2017为例。

# Download the image data.
cd ./images
echo "Downloading MSCOCO train images ..."
curl -LO http://images.cocodataset.org/zips/train2017.zip
echo "Downloading MSCOCO val images ..."
curl -LO http://images.cocodataset.org/zips/val2017.zipcd ../
if [ ! -d annotations ]thenmkdir -p ./annotations
fi# Download the annotation data.
cd ./annotations
echo "Downloading MSCOCO train/val annotations ..."
curl -LO http://images.cocodataset.org/annotations/annotations_trainval2017.zip
echo "Finished downloading. Now extracting ..."# Unzip data
echo "Extracting train images ..."
unzip -qqjd ../images ../images/train2017.zip
echo "Extracting val images ..."
unzip -qqjd ../images ../images/val2017.zip
echo "Extracting annotations ..."
unzip -qqd .. ./annotations_trainval2017.zip

会得到这2个文件夹

在这里插入图片描述
annotation文件夹下有各种json文件,记下它们的路径,后面要用到。

下面说下数据集处理的主要流程,主要用COCO API来提取数据,这个API是conda自带的,不需要另外安装
用的时候import就行了

from pycocotools.coco import COCO

刚才说了annotation文件夹下有json文件,假设这个json文件的路径为ann_path(包括json)
把这个路径传给COCO API

self.coco_api = COCO(ann_path)

然后你就能用这个coco_api提取各种数据,
比如提取类别转为label

self.cat_ids = sorted(self.coco_api.getCatIds())
self.cat2label = {cat_id: i for i, cat_id in enumerate(self.cat_ids)}

提取类别的名称

self.cats = self.coco_api.loadCats(self.cat_ids)
self.class_names = [cat["name"] for cat in self.cats]

提取img_id, 每个id对应一个img文件名,还能根据这个img_id提取对应的annotation,
把img_id对应的信息全部放到img_info里面

self.img_ids = sorted(self.coco_api.imgs.keys()) #这个是全部图片的img_id,需要的时候根据idx提取一个
img_info = self.coco_api.loadImgs(self.img_ids)

所以后面能用img_info干什么呢。
从pytorch的__getitem__函数说起吧,
getitem函数会传入一个idx, 提取这个idx对应的图片和annotation.

我们可以根据上面得到的全部图片的img_id, 也就是self.img_ids, 得到idx对应的img_id
再根据这个img_id得到这个图片对应的annotation

img_id = self.img_ids[idx]
ann_ids = self.coco_api.getAnnIds([img_id])
anns = self.coco_api.loadAnns(ann_ids)

得到图片的文件名,于是可以读取图片

file_name = self.coco_api.loadImgs(img_id)[0]['file_name']
if file_name.startswith('COCO'):file_name = file_name.split('_')[-1]path = osp.join(self.root, file_name)
assert osp.exists(path), 'Image path does not exist: {}'.format(path)img = cv2.imread(path)

下面说如何获得目标框,类别和分割mask
一个图片可能对应多个目标框,所以一个img_id提取出的anns里面可能有多个annotation,
可以用一个循环把它们读出来

for ann in anns:if ann.get("ignore", False):continuex1, y1, w, h = ann["bbox"]  #目标框是(x,y,w,h)形式if ann["area"] <= 0 or w < 1 or h < 1:continueif ann["category_id"] not in self.cat_ids:continuebbox = [x1, y1, x1 + w, y1 + h]  #有需要的话转为(x1,y1,x2,y2)形式gt_bboxes.append(bbox)gt_labels.append(self.cat2label[ann["category_id"]])gt_masks.append(self.coco_api.annToMask(ann).reshape(-1))  #提取分割maskgt_keypoints.append(ann["keypoints"])  #提取特征点

需要注意的是一个图片里面可能没有目标框,也就是annotation为[ ],
这种情况就不要把它当作训练图片了,需要重新采样,
所以需要这样一个流程

    def __getitem__(self, idx):while True:data = self.get_train_data(idx) #annotation为空时要返回Noneif data is None:idx = self.get_another_id()continuereturn datadef get_another_id(self):return np.random.random_integers(0, len(self.data_info) - 1)

在预处理中,如果对图片进行各种变换,不要忘了同时要对目标框,分割mask做同样的变换

示例:

原图
在这里插入图片描述

对图像做翻转,scale,crop变换后

在这里插入图片描述

那么对mask, 目标框也要做同样的变换。

在这里插入图片描述

还有一种情况,annotation不为空,数据是有的,
但是,
在各种预处理变换后,目标没了,这个情况也是要重新采样的

示例:
在这里插入图片描述
它的目标比较小,在左上角的地方,很容易就没了,
比如做如下的预处理变换,

在这里插入图片描述

那怎么判断目标是不是没了呢,
一般来说,目标框经过变换后,会出现x1=x2, 或者y1=y2的情况,
也就是说这个box的w或者h为0

在这里插入图片描述
只需要把w和h很小的box滤掉即可,
滤掉后如果为空,就返回None, 让getitem函数重新采样。

w = meta_data["gt_bboxes"][:, 2] - meta_data["gt_bboxes"][:, 0]
h = meta_data["gt_bboxes"][:, 3] - meta_data["gt_bboxes"][:, 1]keep = (w > self.discard_box_width) * (h > self.discard_box_height)
meta_data["gt_masks"] = torch.FloatTensor(meta_data["gt_masks"][keep])
meta_data["gt_bboxes"] = meta_data["gt_bboxes"][keep]
meta_data["gt_labels"] = meta_data["gt_labels"][keep]if meta["gt_bboxes"].size == 0:return None 
http://www.lryc.cn/news/8329.html

相关文章:

  • 金三银四跳槽季,JAVA面试撸题就来【笑小枫】微信小程序吧~
  • 分享115个HTML电子商务模板,总有一款适合您
  • Python 字符串
  • 总线定义,车载总线:车载etherNet or CAN
  • Python(for和while)循环嵌套及用法
  • 6万字电力行业系统解决方案光伏电站综合安防系统解决方案
  • [Android Studio]Android 数据存储--SQLite数据库存储
  • 学校节能降耗减排方案——能耗监管平台的建设及效果剖析
  • 探索IP地址的应用
  • 点赞破万!阿里面试官总结的2022最新1685页Java面试宝典太全了
  • 项目搭建规范
  • 8.Docker Machine
  • 如何配合使用ESLINT 和 PRETTIER
  • 学英语的优势已来,抓住这个机会
  • 基于微信小程序云开发实现考研题库小程序项目(完整版)
  • AI一点通:使用 ColumnTransformer 转换 Pandas DataFrame 的一个或多个列
  • 【C语言】全局变量、局部变量和静态变量的区别
  • 血氧仪「上潜」,智能穿戴「下沉」
  • CPP2022-计算机类-期末考试
  • 【蓝桥集训】第二天——差分
  • Spring Boot最核心的27个注解,你了解多少?
  • css3弹性盒子
  • 数据分析与SAS学习笔记2
  • 零信任-Akamai零信任介绍(6)
  • 表现良好的最长时段[前缀和思想子数组]
  • Python 获取当前系统时间
  • pytorch基础入门教程
  • RTSP协议交互时TCP/UDP的区别 以及视频和音频的区别 以及H264/H265的区别
  • 调用大智慧L2接口是什么原理?作用是什么?
  • 数据结构 - 栈 与 队列 - (java)