瀏覽代碼

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
 import numpy as np
 from collections import defaultdict, OrderedDict
 from collections import defaultdict, OrderedDict
 import abc
 import abc
 import warnings
 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):
 class BaseAnnotations(abc.ABC):
 	@property
 	@property
@@ -16,6 +19,21 @@ class BaseAnnotations(abc.ABC):
 	def meta(self):
 	def meta(self):
 		pass
 		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):
 	def _path(self, file):
 		return join(self.root, file)
 		return join(self.root, file)
 
 
@@ -103,84 +121,3 @@ class BaseAnnotations(abc.ABC):
 	def test_uuids(self):
 	def test_uuids(self):
 		return self._uuids(self.test_split)
 		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
 #!/usr/bin/env python
 if __name__ != '__main__': raise Exception("Do not import me!")
 if __name__ != '__main__': raise Exception("Do not import me!")
+import sys
+sys.path.insert(0, "..")
 
 
 """
 """
 	Possible calls:
 	Possible calls:

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

@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
 #!/usr/bin/env bash
 PYTHON=python
 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())
+
+