博客:https://www.cnblogs.com/marsggbo/p/11727556.html
官方文档:https://detectron2.readthedocs.io/tutorials/datasets.html
自定义数据层需要实现的步骤:
1:注册DatasetCatalog----将自定义的数据类型转换为detectron2标准的数据格式
2:注册metadataCatalog---(可选)
3:更新配置文件Config
一、注册DatasetCatalog
参考文件/detectron2/data/datasets/pascal_voc.py
# -*- coding: utf-8 -*-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
from fvcore.common.file_io import PathManager
import os
import numpy as np
import xml.etree.ElementTree as ET
from detectron2.structures import BoxMode
from detectron2.data import DatasetCatalog, MetadataCatalog
__all__ = ["register_pascal_voc"]
# fmt: off
CLASS_NAMES = [
"aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat",
"chair", "cow", "diningtable", "dog", "horse", "motorbike", "person",
"pottedplant", "sheep", "sofa", "train", "tvmonitor",
] ##为xml中目标的name名称
# fmt: on
def load_voc_instances(dirname: str, split: str):
"""
Load Pascal VOC detection annotations to Detectron2 format.
Args:
dirname: Contain "Annotations", "ImageSets", "JPEGImages"
split (str): one of "train", "test", "val", "trainval"
"""
with PathManager.open(os.path.join(dirname, "ImageSets", "Main", split + ".txt")) as f:
fileids = np.loadtxt(f, dtype=np.str)
dicts = []
######################
xml解析(省略)
######################
return dicts
def register_pascal_voc(name, dirname, split, year):
DatasetCatalog.register(name, lambda: load_voc_instances(dirname, split))
MetadataCatalog.get(name).set(
thing_classes=CLASS_NAMES, dirname=dirname, year=year, split=split
)
/detectron2/data/datasets/builtin.py中注册实现:
# ==== Predefined splits for PASCAL VOC ===========
def register_all_pascal_voc(root="datasets"):
SPLITS = [
("voc_2007_trainval", "VOC2007", "trainval"),
("voc_2007_train", "VOC2007", "train"),
("voc_2007_val", "VOC2007", "val"),
("voc_2007_test", "VOC2007", "test"),
("voc_2012_trainval", "VOC2012", "trainval"),
("voc_2012_train", "VOC2012", "train"),
("voc_2012_val", "VOC2012", "val"),
] ##该列表中的名称与configs中yaml中DATASETS.{TRAIN,TEST}中的名字完全一致
for name, dirname, split in SPLITS:
year = 2007 if "2007" in name else 2012
register_pascal_voc(name, os.path.join(root, dirname), split, year)
MetadataCatalog.get(name).evaluator_type = "pascal_voc"
步骤:
1:实现函数load_voc_instances,返回detectron2标准数据格式。
标准数据格式:datasetFormat=[dict1,dict2,dict3,....] ##len(datasetFormat)为数据集大小,一张图像对应一个dict
dict1={
"file_name":str, ##图像绝对路径
"image_id":str or int,
"annotations":[ ##list[dict]
{
"category_id":int, ##类别索引,CLASS_NAMES.index(cls)的返回值,cls为类别名name
"bbox":[float,float,float,float], ##排列顺序与下面bbox_mode有关
"bbox_mode":int ##XYXY_ABS:[xmin,ymin,xmax,ymax] XYWH_ABS:[xmin,ymin,width,height]
##XYXY_REL XYWH 相对与图像尺寸的坐标值,范围[0,1]
},
{
},
]
}
2:注册DatasetCatalog
def register_pascal_voc(name, dirname, split, year):
DatasetCatalog.register(name, lambda: load_voc_instances(dirname, split))
#################################
类DatasetCatalog中register函数的定义
@staticmethod
def register(name,func):
"""
Args:
name (str): the name that identifies a dataset, e.g. "coco_2014_train".
func (callable): a callable which takes no arguments and returns a list of dicts.
"""
#############################
此处使用了lambda表达式
作用:借助lambda给回调函数传参,做了一个“函数打包”的操作,它把函数和它的参数列表打包在一起,得到一个新的函数,
实际传入到register的并不是原来的load_voc_instances,而是打包得到的新函数。至于这个新函数叫做什么名字,对于
我们来说是无所谓的(匿名函数),反正也只用这一次,下次还要用的话,lambda会再一次重新打包,得到新的匿名函数。
二、注册metadataCatalog -----没太明白具体是做什么用的,后续若有新的理解在进行补充
参考博客https://www.cnblogs.com/marsggbo/p/11727556.html
MetadataCatalog
的作用是记录数据集的一些特征,这样我们就可以很方便的在整个代码中获取数据集的特征信息。在注册DatasetCatalog
后,我们可以按如下栗子对MetadataCatalog
进行注册并定义我们后面可能会用到的属性特征:
from detectron2.data import MetadataCatalog
MetadataCatalog.get("my_dataset").thing_classes = ["person", "dog"]
# 也可以这样
MetadataCatalog.get("my_dataset").set("thing_classes",["person", "dog"])
注意:如果你的数据集名字未注册过,MetadataCatalog.get
会自动进行注册,然后会自动设置你所设定的属性值。
其实MetadataCatalog
还有其他的特征属性可以设置,如stuff_classes
,stuff_colors
等等。你可能会好奇thing_classes
和stuff_classes
有什么区别,区别如下:
thing_classes
用于指定instance-level任务,stuff_classes
用于semantic segmentation任务。thing
,所以用于instance-level;而雪、天空这种不可数的就理解成stuff
,所以用于semantic segmentation。参考On Seeing Stuff: The Perception of Materials by Humans and Machines最后,get_detection_dataset_dicts
会返回一个包含若干个dict的list,之所以是list是因为参数dataset_names
也是一个list,这样我们就可以制定多个names来同时对数据进行读取。
三、修改配置文件 在对应加载的配置文件如/configs/PascalVOC-Detection/faster_rcnn_R_50_FPN.yaml中修改MODEL.NUM_CLASSES参数
DATASETS.{TRAIN,TEST}参数
。。。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。