瀏覽代碼

added Flowers102 dataset info and annotations reading implementation

Dimitri Korsch 6 年之前
父節點
當前提交
01ff006ddf

+ 1 - 1
nabirds/__init__.py

@@ -1,4 +1,4 @@
 from .dataset import Dataset, ImageWrapperDataset
 from .annotations import NAB_Annotations, CUB_Annotations
 
-__version__ = "0.3.3"
+__version__ = "0.3.4"

+ 3 - 0
nabirds/annotations/__init__.py

@@ -2,6 +2,7 @@ from .cub import CUB_Annotations
 from .nab import NAB_Annotations
 from .cars import CARS_Annotations
 from .inat import INAT19_Annotations
+from .flowers import FLOWERS_Annotations
 
 from cvargparse.utils import BaseChoiceType
 from functools import partial
@@ -10,6 +11,8 @@ class AnnotationType(BaseChoiceType):
 	CUB200 = CUB_Annotations
 	NAB = NAB_Annotations
 	CARS = CARS_Annotations
+	FLOWERS = FLOWERS_Annotations
+
 	INAT19 = INAT19_Annotations
 	INAT19_MINI = partial(INAT19_Annotations)
 	INAT19_TEST = partial(INAT19_Annotations)

+ 18 - 1
nabirds/annotations/base.py

@@ -13,6 +13,23 @@ def _parse_index(idx, offset):
 		idx = str(int(idx) - offset)
 	return idx
 
+class BBoxMixin(abc.ABC):
+	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()
+
+
 class BaseAnnotations(abc.ABC):
 
 	FEATURE_PHONY = dict(train=["train"], test=["test", "val"])
@@ -168,7 +185,7 @@ class BaseAnnotations(abc.ABC):
 
 	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 [i.split() for i in self._split]}
+		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)
 

+ 2 - 23
nabirds/annotations/cars.py

@@ -3,10 +3,10 @@ import numpy as np
 from os.path import join
 
 from nabirds.utils import _MetaInfo
-from .base import BaseAnnotations
+from .base import BaseAnnotations, BBoxMixin
 
 
-class CARS_Annotations(BaseAnnotations):
+class CARS_Annotations(BaseAnnotations, BBoxMixin):
 	name="CARS"
 
 	@property
@@ -37,12 +37,6 @@ class CARS_Annotations(BaseAnnotations):
 		# set labels from [1..N] to [0..N-1]
 		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):
 		self.part_names = {}
 
@@ -52,22 +46,7 @@ class CARS_Annotations(BaseAnnotations):
 
 		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 parts(self, *args, **kwargs):
 		if self.has_parts:
 			return super(CARS_Annotations, self).parts(*args, **kwargs)
 		return None
-
-	def bounding_box(self, uuid):
-		return self.bounding_boxes[self.uuid_to_idx[uuid]].copy()

+ 2 - 18
nabirds/annotations/cub.py

@@ -3,10 +3,10 @@ import numpy as np
 from os.path import join
 
 from nabirds.utils import _MetaInfo
-from .base import BaseAnnotations
+from .base import BaseAnnotations, BBoxMixin
 
 
-class CUB_Annotations(BaseAnnotations):
+class CUB_Annotations(BaseAnnotations, BBoxMixin):
 	name="CUB200"
 
 	@property
@@ -50,19 +50,3 @@ class CUB_Annotations(BaseAnnotations):
 		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()

+ 47 - 0
nabirds/annotations/flowers.py

@@ -0,0 +1,47 @@
+import numpy as np
+
+from os.path import join
+
+from nabirds.utils import _MetaInfo
+from .base import BaseAnnotations, BBoxMixin
+
+
+class FLOWERS_Annotations(BaseAnnotations, BBoxMixin):
+	name="FLOWERS"
+
+	@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.bounding_boxes, "_bounding_boxes"],
+			# [info.parts_file, "_part_locs"],
+			# [info.part_names_file, "_part_names"],
+		]
+		return info
+
+	def _load_parts(self):
+		self.part_names = {}
+
+		# load only if present
+		if self.has_parts:
+			super(CARS_Annotations, self)._load_parts(idx_offset=1)
+
+		self._load_bounding_boxes()
+
+	def parts(self, *args, **kwargs):
+		if self.has_parts:
+			return super(CARS_Annotations, self).parts(*args, **kwargs)
+		return None

+ 6 - 3
nabirds/annotations/nab.py

@@ -32,6 +32,9 @@ class NAB_Annotations(BaseAnnotations):
 		]
 		return info
 
-	def bounding_box(self, uuid):
-		return np.array((0,0,1,1),
-			dtype=self.meta.bounding_box_dtype)
+	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 [i.split() for i in 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)
+

+ 9 - 0
scripts/info_files/info.yml

@@ -65,6 +65,11 @@ DATASETS:
     annotations: "ORIGINAL"
     n_classes: 196
 
+  FLOWERS:         &flowers
+    folder: flowers
+    annotations: "flowers102"
+    n_classes: 102
+
   INAT19:         &inat19
     folder: inat
     annotations: "2019"
@@ -140,6 +145,10 @@ PARTS:
     <<: *nabirds
     <<: *parts_global
 
+  FLOWERS_GLOBAL:
+    <<: *flowers
+    <<: *parts_global
+
   INAT19_GLOBAL:
     <<: *inat19
     <<: *parts_global