创建新的数据集范式
尚未完成
想创建一个新的数据集,基于coco建立新的数据集,首先了解coco数据集的接口以及定义。
注意,pipeline与json文件,json文件应该是原始数据重构得到的标注文件,不要在原始数据中对数据做修改,而在pipeline中修改json文件的标注内容。
obj01 ape
obj02 benchvise
obj03 bowl
obj04 cam
obj05 can
obj06 cat
obj07 cup
obj08 driller
obj09 duck
obj10 eggbox
obj11 glue
obj12 Holepuncher
obj13 iron
obj14 lamp
obj15 phone
由于linemod_preprocessed中已定义的训练数据集过少,所以将train.txt与test.txt互换
为复现yolo6d,将采用linemod_proprecessed数据集,由于linemod bop与linemod_proprecessed文件结构不同,为了不对原文件做出改动,所以将分成两个制作json脚本;
一共八个角点,分别为:
[[min_x, min_y, min_z], [min_x, min_y, max_z],
[min_x, max_y, min_z], [min_x, max_y, max_z],
[max_x, min_y, min_z], [max_x, min_y, max_z],
[max_x, max_y, min_z], [max_x, max_y, max_z]]
一共15个模型信息,为了节省内存损耗,在使用ply信息时,使用map来对ply文件进行索引。
base_dataset
def force_full_initclass BaseDataset:METAINFO_fully_initializeddef __init__() # 构造函数def get_data_info(self, idx) # 根据idx返回data_list数据信息def full_init # def metainfo(self) # 获取_metainfo信息def parse_data_info(self, raw_data_info:dict)* # 从ann_file中解析标注信息def filter_data # 过滤def get_cat_ids # 获取idx对应的类别信息def __getitem__ # 根据idx求索引值def load_data_list(self)** # 通过ann_file加载标注信息,并格式化格式def _load_metainfo(cls, metainfo) # 加载self.metainfo信息def _join_prefix(self) # 将根目录与文件前缀链接def get_subset_(self, indices) # 将自身变为子数据集def get_subset # return子数据集def _get_serialized_subset # 获取序列数据集def _get_unserialized_subset # 获取无序数据集def _serialize_data # full_init调用def rand_another # 获取随机数def prepare_data # 获得经过pipeline返回的值def __len__ # 数据集长度def _copy_without_annotation # 对annotation深拷贝
实例化一个dataset
方法一:直接实例化一个类
dataset = YOLO6DDataset(data_root=data_root,ann_file=train_ann_file,data_prefix=dict(img_path='data/02/rgb/'),filter_cfg=None,pipeline=train_pipeline)
方法二:创建一个dict,然后build
dataset = dict(type=YOLO6DDataset,ann_file=train_ann_file,data_prefix=dict(img_path='data/02/rgb/'),filter_cfg=None,pipeline=train_pipeline)dataset = DATASETS.build(dataset)
在初始化数据集中,full_init()
有很重要的作用,
- 通过
load_data_list()
加载json文件中的信息,该函数仅在full_init
中调用 - 通过
filter_data()
过滤信息 - 根据
dataset
中是否存在_indices
,来获取unserialize_data
- 根据
serialize_data
,来得到data_bytes
和data_address
额外说明:
load_data_list()
是对json文件中data_list
部分进行处理,通过parse_data_info()
将其转为目标形式的data_list
Transform
在得到数据集后,并没有具体的图片信息,为了通过json文件信息dataset.data_list
获取实例的图片和标注信息,就需要设定pipeline
中的LoadImageFromFile
和Load6DAnnotations
对结果进行处理。
1、首先要从数据集中得到具体的数据: data_info = dataset.get_data_info(idx)
2、对具体数据进行pipeline处理: dataset.pipleline(data_info)
在DATASET
的方法中,prepare_data
已经包含上述两个流程,所以可以采用:
result = dataset.prepare_data(1)
另外,可以直接索引,在__getitem__
中包含了prepare_data
方法
dataset[1]
PackInputs
为了能够在不同模块之间传输数据,在对数据处理之后,还需要对输入数据进行打包,即PackInputs
该数据处理最后返回一个dict,其中包括
dict:- 'inputs': 前向传播到model中数据- 'data_sample':打包数据的真值样本
-
inputs
就是传输进入的数据,例如一张图; -
data_sample
通过建立DataSample
和InstanceData
来构建,其中mapping_table
中的属性是为了构建InstanceData
而定,构件好InstanceData
之后,传入DataSample
对象中;另外,根据在类初始化的时候所建立的meat_keys
,建立metainfo
对象,并赋给data_sample
以上为构建PackInputs的流程。其中DataSample
和InstanceData
需要重写一下,流程如下。
DataSample
父类:BaseDataElement
,支持Tensor-like和dict-like操作的基本数据接口
包含的元素可分为两类:data
和 metainfo
,其中data
一般为任务上的预测结果和真值,另一个metainfo
是示例数据,例如img_id
、img_shape
、img_path
等。
DataSample
的初始化
def __init__(self, *, metainfo: Optional[dict] = None, **kwargs) -> None:self._metainfo_fields: set = set()self._data_fields: set = set()if metainfo is not None:self.set_metainfo(metainfo=metainfo)if kwargs:self.set_data(kwargs)
通过set_metainfo
和set_data
来实例化属性,其中_metainfo_fields
和_data_fields
保存实例化的属性名称。
后期需要更改的地方:
关于instances应该有什么
不同任务应该有不同的instance,例如2d检测使用instances,语义分割用seg_instances