使用mmdetection训练supervisely-person-datasets

       supervisely-person-datasets是deepsystems.ai开源的一个人像分割数据集。专门用于人像的精细化语义分割。该数据集包含5711张图片,有6884个高质量的标注的人体实例。关于该数据集的下载,终于!Supervise.ly 发布人像分割数据集啦(免费开源)这篇文章介绍的比较清楚。一开始下载下来的数据集标注文件使用的是.json格式保存,部分人体标注信息采用polygon的形式给出的,而大部分则是通过bitmap形式给出的,这和常用数据集比如COCO,PASCAL VOC数据集相比,可读性非常差,好在supervisely开源了数据集使用的API接口。本文就主要介绍这个数据集使用的API接口。

supervisely-person-datasets数据集下载

       这个数据集包含13个文件夹(ds1~ds13),每个文件夹中包含img和ann两个文件夹,前者是图片集合后者是对应图片集合的.json格式标注文件。整个数据集下载下来大约7.2G左右,不过该数据集需要使用外网才能下载下来,而且数据集下载很慢。建议分部分下载,这样下载效率更高。我自己下载下来并上传至百度云盘,考虑到版权问题,不予公开,如果您的网络下载不了,可以邮箱私信我。数据集部分图片如下所示

数据集下载下来的结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
niceliu@ise:/mnt/software/datasets/supervisely-person-datasets$ tree -L 2
.
├── ds1
│ ├── ann
│ └── img
...
├── ds11
│ ├── ann
│ └── img
├── ds12
│ ├── ann
│ └── img
├── ds13
│ ├── ann
│ └── img
└── meta.json

这个数据集中所有图片都是在Pexels上下载的,每张图片均为高清图片,可做壁纸哈。deepsystem.io开源了这个网站的图片下载工具Pexels Downloader。注意:这个数据集下载下来之后包含meta.json文件不可删除,不然后续API无法解析这个数据集。

API下载及使用

       supervisely这个repository中的supervisely_lib包含了supervisely数据格式的API接口。把这个repository克隆下来。在这个文件help/jupyterlab_scripts/src/tutorials/01_project_structure/project.ipynb详细地介绍了supervisely数据格式的读取以及可视化。这里主要列举一些与supervisely-person-datasets相关的接口。

数据集载入jiy以及基本信息读取

1
2
3
4
5
6
7
8
9
10
11
12
# Supervisely Python SDK

import numpy as np
import matplotlib.pyplot as plt
import supervisely_lib as sly
################打开数据集
project = sly.Project('/mnt/software/datasets/supervisely-person-datasets/', sly.OpenMode.READ)
#打印数据集相关信息
print("Project name: ", project.name)
print("Project directory: ", project.directory)
print("Total images: ", project.total_items)
print("Dataset names: ", project.datasets.keys())

打印信息如下:

1
2
3
4
Project name:  supervisely-person-datasets
Project directory: /mnt/software/datasets/supervisely-person-datasets
Total images: 5711
Dataset names: ['ds7', 'ds3', 'ds4', 'ds1', 'ds8', 'ds9', 'ds2', 'ds5', 'ds13', 'ds6', 'ds12', 'ds11', 'ds10']

数据集遍历

1
2
3
4
5
6
for dataset in project:
print("Dataset: ", dataset.name)
for item_name in dataset:
ann_path=dataset.get_ann_path(item_name)
img_path = dataset.get_img_path(item_name)
print(" image & anno: ", img_path,ann_path)

打印输出的是单张图片路径以及对应标注文件路径:

1
image & anno:  /mnt/software/datasets/supervisely-person-datasets/ds10/img/pexels-photo-450596.png /mnt/software/datasets/supervisely-person-datasets/ds10/ann/pexels-photo-450596.png.json

标注信息读取并显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def display_images(images, figsize=None):
plt.figure(figsize=(figsize if (figsize is not None) else (15, 15)))
for i, img in enumerate(images, start=1):
plt.subplot(1, len(images), i)
plt.imshow(img)
# 定位并加载图像标签数据。
item_paths = project.datasets.get('ds1').get_item_paths('pexels-photo-708392.png')
ann = sly.Annotation.load_json_file(item_paths.ann_path, project.meta)
# 检查标记的对象并打印出基本属性。
for label in ann.labels:
print('Found label object: ' + label.obj_class.name)
print(' geometry type: ' + label.geometry.geometry_name())
print(' object area: ' + str(label.geometry.area))

# 读取底层原始图像以进行显示。
img = sly.image.read(item_paths.img_path)

# 使用meta.json文件中的颜色呈现所有标签。
ann_render = np.zeros(ann.img_size + (3,), dtype=np.uint8)
ann.draw(ann_render)

# 分别绘制标记的对象轮廓。
ann_contours = np.zeros(ann.img_size + (3,), dtype=np.uint8)
ann.draw_contour(ann_contours, thickness=7)
#显示
display_images([img, ann_render, ann_contours])

对应显示结果如下:

打印信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
Found label object: person_bmp
geometry type: bitmap
object area: 87746.0
Found label object: person_bmp
geometry type: bitmap
object area: 153198.0
Found label object: person_bmp
geometry type: bitmap
object area: 92894.0
Found label object: person_bmp
geometry type: bitmap
object area: 109706.0

值得注意的是,在这个数据集中geometry类型除了bitmap格式还有polygon格式。polygon格式对应显示如下:

获取边框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
rendered_bboxes = np.zeros(ann.img_size + (3,), dtype=np.uint8)

for label in ann.labels:
print('Label type: ' + label.geometry.geometry_name())

# Same call for any label type.
bbox = label.geometry.to_bbox()
print('Label bounding box: [{}, {}, {}, {}]'.format(
bbox.top, bbox.left, bbox.bottom, bbox.right))

# Draw the bounding boxes.
bbox.draw_contour(rendered_bboxes, color = label.obj_class.color, thickness=20)

# Draw the labels themselves too to make sure the bounding boxes are correct.
label.geometry.draw(rendered_bboxes, color=[int(x/2) for x in label.obj_class.color])

display_images([img, rendered_bboxes])

边框显示如下:

熟悉了这个数据集标注信息的读取尤其是边框box以及掩膜mask,接下来就可以使用一些现有的模型进行训练。

使用mmdetection训练

在使用mmdetection训练这个数据集的时候,主要修改如下部分:
(1)选择合适模型,并编写该模型的配置文件,比如maskrcnn,修改相关参数,比如数据集相关参数,以及优化器学习率,总的迭代次数;
(2)在mmdet/datasets文件夹中实现自己的数据集加载部分代码,可参考coco.py的实现,实现之后,在mmdet/datasets/init.py中添加自己的数据集加载类;
(3)在mmdet/core/evaluation/class_names.py中添加自己的数据集类别名声明

之后就可以开始训练自己的数据集。由于这个数据集规模算比较小,而且考虑到计算资源问题,为了让模型更加快速的收敛,我选择在已经在coco上训练好的maskrcnn预训练模型来训练该数据集。测试结果如下:

最后,使用mmdetection训练supervisely person 数据集的源码在这里,https://github.com/nicehuster/mmdetection-supervisely-person-datasets

数据集下载地址: 链接: https://pan.baidu.com/s/14J3uXxLaVHOvAToTIDeRCw 提取码: iu9v