ソースを参照

first reading attempts

Dimitri Korsch 6 年 前
コミット
329cd72f96

+ 2 - 0
nabirds/annotations/__init__.py

@@ -0,0 +1,2 @@
+from .cub import CUB_Annotations
+from .nab import NAB_Annotations

+ 24 - 87
nabirds/annotations.py → nabirds/annotations/base.py

@@ -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()

+ 68 - 0
nabirds/annotations/cub.py

@@ -0,0 +1,68 @@
+import numpy as np
+
+from os.path import join
+
+from nabirds.utils import _MetaInfo
+from .base import BaseAnnotations
+
+
+class CUB_Annotations(BaseAnnotations):
+	name="CUB200"
+
+	@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()

+ 30 - 0
nabirds/annotations/nab.py

@@ -0,0 +1,30 @@
+from os.path import join
+
+from nabirds.utils import _MetaInfo
+from .base import BaseAnnotations
+
+
+class NAB_Annotations(BaseAnnotations):
+	name="NABirds"
+
+	@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

+ 19 - 0
nabirds/utils.py

@@ -0,0 +1,19 @@
+class attr_dict(dict):
+	def __getattr__(self, name):
+		if name in self:
+			return self[name]
+		else:
+			return super(attr_dict, self).__getattr__(name)
+
+	def __getitem__(self, key):
+		res = super(attr_dict, self).__getitem__(key)
+
+		if isinstance(res, dict):
+			return attr_dict(res)
+		return res
+
+class _MetaInfo(object):
+	def __init__(self, **kwargs):
+		for name, value in kwargs.items():
+			setattr(self, name, value)
+		self.structure = []

+ 2 - 0
nabirds/display.py → scripts/display.py

@@ -1,5 +1,7 @@
 #!/usr/bin/env python
 if __name__ != '__main__': raise Exception("Do not import me!")
+import sys
+sys.path.insert(0, "..")
 
 """
 	Possible calls:

+ 1 - 1
display.sh → scripts/display.sh

@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
 PYTHON=python
 
-$PYTHON nabirds/display.py $@
+$PYTHON display.py $@
 

+ 76 - 0
scripts/display_from_info.py

@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+if __name__ != '__main__': raise Exception("Do not import me!")
+import sys
+sys.path.insert(0, "..")
+
+try:
+	from yaml import CLoader as Loader, CDumper as Dumper
+except ImportError:
+	from yaml import Loader, Dumper
+
+import yaml
+import logging
+from argparse import ArgumentParser
+
+from nabirds import CUB_Annotations, Dataset
+
+
+def init_logger(args):
+	fmt = "%(levelname)s - [%(asctime)s] %(filename)s:%(lineno)d [%(funcName)s]: %(message)s"
+	logging.basicConfig(
+		format=fmt,
+		level=getattr(logging, args.loglevel.upper(), logging.DEBUG),
+		filename=args.logfile or None,
+		filemode="w")
+
+
+def main(args):
+	init_logger(args)
+
+	annot = CUB_Annotations.from_info_file(
+		args.info, args.parts, args.feature_model)
+	logging.info("Loaded data from \"{}\"".format(annot.root))
+
+	uuids = getattr(annot, "{}_uuids".format(args.subset))
+
+	data = Dataset(
+		uuids=uuids, annotations=annot,
+		seed=args.seed
+	)
+
+	logging.info("Loaded {} {} images".format(len(data), args.subset))
+
+
+
+parser = ArgumentParser()
+
+parser.add_argument("info")
+
+parser.add_argument("--parts", "-p",
+	choices=["GT", "GT2", "NAC", "L1_pred", "L1_full"]
+)
+
+parser.add_argument("--feature_model",
+	choices=["inception", "inception_tf", "resnet"]
+)
+
+parser.add_argument("--subset", "-s",
+	help="Possible subsets: train, test",
+	choices=["train", "test"],
+	default="train", type=str)
+
+parser.add_argument(
+	'--logfile', type=str, default='',
+	help='File for logging output')
+
+parser.add_argument(
+	'--loglevel', type=str, default='INFO',
+	help='logging level. see logging module for more information')
+
+parser.add_argument(
+	'--seed', type=int, default=12311123,
+	help='random seed')
+
+main(parser.parse_args())
+
+