|
@@ -1,14 +1,17 @@
|
|
|
-from os.path import join, isfile
|
|
|
+from os.path import join, isfile, isdir
|
|
|
import numpy as np
|
|
|
from collections import defaultdict, OrderedDict
|
|
|
import abc
|
|
|
import warnings
|
|
|
|
|
|
-class _MetaInfo(object):
|
|
|
- def __init__(self, **kwargs):
|
|
|
- for name, value in kwargs.items():
|
|
|
- setattr(self, name, value)
|
|
|
- self.structure = []
|
|
|
+try:
|
|
|
+ from yaml import CLoader as Loader, CDumper as Dumper
|
|
|
+except ImportError:
|
|
|
+ from yaml import Loader, Dumper
|
|
|
+
|
|
|
+import yaml
|
|
|
+
|
|
|
+from nabirds.utils import attr_dict
|
|
|
|
|
|
class BaseAnnotations(abc.ABC):
|
|
|
@property
|
|
@@ -16,6 +19,21 @@ class BaseAnnotations(abc.ABC):
|
|
|
def meta(self):
|
|
|
pass
|
|
|
|
|
|
+ @classmethod
|
|
|
+ def from_info_file(cls, info_file, parts=None, feature_model=None):
|
|
|
+ with open(info_file) as f:
|
|
|
+ info = attr_dict(yaml.load(f, Loader=Loader))
|
|
|
+
|
|
|
+ data_root = join(info.BASE_DIR, info.DATA_DIR)
|
|
|
+ if parts is None:
|
|
|
+ dataset_info = info.DATASETS[cls.name]
|
|
|
+ else:
|
|
|
+ dataset_info = info.PARTS[parts]
|
|
|
+ annot_dir = join(data_root, dataset_info.folder, dataset_info.annotations)
|
|
|
+
|
|
|
+ assert isdir(annot_dir), "Annotation folder does exist! \"{}\"".format(annot_dir)
|
|
|
+ return cls(annot_dir, parts=info, feature_model...)
|
|
|
+
|
|
|
def _path(self, file):
|
|
|
return join(self.root, file)
|
|
|
|
|
@@ -103,84 +121,3 @@ class BaseAnnotations(abc.ABC):
|
|
|
def test_uuids(self):
|
|
|
return self._uuids(self.test_split)
|
|
|
|
|
|
-class NAB_Annotations(BaseAnnotations):
|
|
|
- @property
|
|
|
- def meta(self):
|
|
|
- info = _MetaInfo(
|
|
|
- images_folder="images",
|
|
|
- images_file="images.txt",
|
|
|
- labels_file="labels.txt",
|
|
|
- hierarchy_file="hierarchy.txt",
|
|
|
- split_file="train_test_split.txt",
|
|
|
- parts_file=join("parts", "part_locs.txt"),
|
|
|
- part_names_file=join("parts", "parts.txt"),
|
|
|
- )
|
|
|
-
|
|
|
- info.structure = [
|
|
|
- [info.images_file, "_images"],
|
|
|
- [info.labels_file, "labels"],
|
|
|
- [info.hierarchy_file, "hierarchy"],
|
|
|
- [info.split_file, "_split"],
|
|
|
- [info.parts_file, "_part_locs"],
|
|
|
- [info.part_names_file, "_part_names"],
|
|
|
- ]
|
|
|
- return info
|
|
|
-
|
|
|
-class CUB_Annotations(BaseAnnotations):
|
|
|
- @property
|
|
|
- def meta(self):
|
|
|
- info = _MetaInfo(
|
|
|
- images_folder="images",
|
|
|
- images_file="images.txt",
|
|
|
- labels_file="labels.txt",
|
|
|
- split_file="tr_ID.txt",
|
|
|
- bounding_boxes="bounding_boxes.txt",
|
|
|
- bounding_box_dtype=np.dtype([(v, np.int32) for v in "xywh"]),
|
|
|
- parts_file=join("parts", "part_locs.txt"),
|
|
|
- part_names_file=join("parts", "parts.txt"),
|
|
|
-
|
|
|
- )
|
|
|
-
|
|
|
- info.structure = [
|
|
|
- [info.images_file, "_images"],
|
|
|
- [info.labels_file, "labels"],
|
|
|
- [info.split_file, "_split"],
|
|
|
- [info.parts_file, "_part_locs"],
|
|
|
- [info.part_names_file, "_part_names"],
|
|
|
- [info.bounding_boxes, "_bounding_boxes"],
|
|
|
- ]
|
|
|
- return info
|
|
|
-
|
|
|
- def __init__(self, *args, **kwargs):
|
|
|
- super(CUB_Annotations, self).__init__(*args, **kwargs)
|
|
|
- # set labels from [1..200] to [0..199]
|
|
|
- self.labels -= 1
|
|
|
-
|
|
|
- def _load_split(self):
|
|
|
- assert self._split is not None, "Train-test split was not loaded!"
|
|
|
- uuid_to_split = {uuid: int(split) for uuid, split in zip(self.uuids, self._split)}
|
|
|
- self.train_split = np.array([uuid_to_split[uuid] for uuid in self.uuids], dtype=bool)
|
|
|
- self.test_split = np.logical_not(self.train_split)
|
|
|
-
|
|
|
- def _load_parts(self):
|
|
|
- super(CUB_Annotations, self)._load_parts()
|
|
|
- # set part idxs from 1-idxs to 0-idxs
|
|
|
- self.part_locs[..., 0] -= 1
|
|
|
-
|
|
|
- self._load_bounding_boxes()
|
|
|
-
|
|
|
- def _load_bounding_boxes(self):
|
|
|
- assert self._bounding_boxes is not None, "Bouding boxes were not loaded!"
|
|
|
-
|
|
|
- uuid_to_bbox = {}
|
|
|
- for content in [i.split() for i in self._bounding_boxes]:
|
|
|
- uuid, bbox = content[0], content[1:]
|
|
|
- uuid_to_bbox[uuid] = [float(i) for i in bbox]
|
|
|
-
|
|
|
- self.bounding_boxes = np.array(
|
|
|
- [tuple(uuid_to_bbox[uuid]) for uuid in self.uuids],
|
|
|
- dtype=self.meta.bounding_box_dtype)
|
|
|
-
|
|
|
-
|
|
|
- def bounding_box(self, uuid):
|
|
|
- return self.bounding_boxes[self.uuid_to_idx[uuid]].copy()
|