Преглед изворни кода

added iNaturalist annotations logic

Dimitri Korsch пре 6 година
родитељ
комит
f59a90b67a

+ 2 - 0
nabirds/annotations/__init__.py

@@ -1,6 +1,7 @@
 from .cub import CUB_Annotations
 from .nab import NAB_Annotations
 from .cars import CARS_Annotations
+from .inat import INAT19_Annotations
 
 from cvargparse.utils import BaseChoiceType
 
@@ -8,5 +9,6 @@ class AnnotationType(BaseChoiceType):
 	CUB200 = CUB_Annotations
 	NAB = NAB_Annotations
 	CARS = CARS_Annotations
+	INAT19 = INAT19_Annotations
 
 	Default = CUB200

+ 4 - 2
nabirds/annotations/base.py

@@ -30,9 +30,8 @@ class BaseAnnotations(abc.ABC):
 		for fname, attr in self.meta.structure:
 			self.read_content(fname, attr)
 
-		self.labels = np.array([int(l) for l in self.labels], dtype=np.int32)
-
 		self._load_uuids()
+		self._load_labels()
 		self._load_parts()
 		self._load_split()
 
@@ -126,6 +125,9 @@ class BaseAnnotations(abc.ABC):
 		setattr(self, attr, content)
 
 
+	def _load_labels(self):
+		self.labels = np.array([int(l) for l in self.labels], dtype=np.int32)
+
 	def _load_uuids(self):
 		assert self._images is not None, "Images were not loaded!"
 		uuid_fnames = [i.split() for i in self._images]

+ 71 - 0
nabirds/annotations/inat.py

@@ -0,0 +1,71 @@
+import numpy as np
+import simplejson as json
+
+from os.path import join
+
+from nabirds.utils import _MetaInfo
+
+from .base import BaseAnnotations
+
+class INAT19_Annotations(BaseAnnotations):
+
+	name="INAT19"
+
+	@property
+	def meta(self):
+		info = _MetaInfo(
+			images_folder="",
+			content="trainval2019.json",
+			val_content="val2019.json",
+			# train_content="train2019.json",
+
+			# fake bounding boxes: the whole image
+			bounding_box_dtype=np.dtype([(v, np.int32) for v in "xywh"])
+		)
+
+		info.structure = [
+			[info.content, "_content"],
+			[info.val_content, "_val_content"],
+		]
+		return info
+
+	def read_content(self, json_file, attr):
+		with self._open(json_file) as f:
+			content = json.load(f)
+			setattr(self, attr, content)
+
+	def parts(self, uuids):
+		return None
+
+	def bounding_box(self, uuid):
+		return self.bounding_boxes[self.uuid_to_idx[uuid]].copy()
+
+	def _load_bounding_boxes(self):
+		self.bounding_boxes = np.zeros(len(self.uuids), dtype=self.meta.bounding_box_dtype)
+
+		for i, im in enumerate(self._content["images"]):
+			self.bounding_boxes[i]["w"] = im["width"]
+			self.bounding_boxes[i]["h"] = im["height"]
+
+	def _load_parts(self):
+		self.part_names = {}
+		self._load_bounding_boxes()
+
+	def _load_split(self):
+		self.train_split = np.ones(len(self.uuids), dtype=bool)
+		val_uuids = [im["id"] for im in self._val_content["images"]]
+		for v_uuid in val_uuids:
+			self.train_split[self.uuid_to_idx[v_uuid]] = False
+
+		self.test_split = np.logical_not(self.train_split)
+
+	def _load_labels(self):
+		self.labels = np.zeros(len(self.uuids), dtype=np.int32)
+		labs = {annot["image_id"]: annot["category_id"] for annot in self._content["annotations"]}
+		for uuid in self.uuids:
+			self.labels[self.uuid_to_idx[uuid]] = labs[uuid]
+
+	def _load_uuids(self):
+		uuid_fnames = [(im["id"], im["file_name"]) for im in self._content["images"]]
+		self.uuids, self.images = map(np.array, zip(*uuid_fnames))
+		self.uuid_to_idx = {uuid: i for i, uuid in enumerate(self.uuids)}

+ 3 - 1
scripts/display.py

@@ -13,8 +13,10 @@ from nabirds.annotations import AnnotationType
 from utils import parser, plot_crops
 
 def main(args):
+	assert args.dataset in AnnotationType, \
+		"AnnotationType is not known: \"{}\"".format(args.dataset)
 
-	annotation_cls = AnnotationType.get(args.dataset).value
+	annotation_cls = AnnotationType[args.dataset].value
 
 	logging.info("Loading \"{}\" annnotations from \"{}\"".format(args.dataset, args.data))
 	annot = annotation_cls(args.data, args.parts, args.feature_model)

+ 10 - 0
scripts/info_files/info.yml

@@ -60,6 +60,11 @@ DATASETS:
     annotations: ORIGINAL
     n_classes: 196
 
+  INAT19:         &inat19
+    folder: inat
+    annotations: "2019"
+    n_classes: 1010
+
 ############ Existing Part Annotations and Part Features
 ### feature file name composition:
 # ${BASE_DIR}/${DATA_DIR}/${DATASETS:folder}/${PART_TYPES:annotations}/features
@@ -117,6 +122,11 @@ PART_TYPES:
       - 0.31
 
 PARTS:
+  #### No Parts Annotations
+  INAT19_GLOBAL:
+    <<: *inat19
+    <<: *parts_global
+
   #### No Parts Annotations
   CUB200_GLOBAL:
     <<: *cub200