annotations.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. from os.path import join, isfile
  2. import numpy as np
  3. from collections import defaultdict
  4. class Annotations(object):
  5. class meta:
  6. images_file = "images.txt"
  7. images_folder = "images"
  8. labels_file = "labels.txt"
  9. hierarchy_file = "hierarchy.txt"
  10. split_file = "train_test_split.txt"
  11. parts_file = join("parts", "part_locs.txt")
  12. structure = [
  13. [images_file, "_images"],
  14. [labels_file, "labels"],
  15. [hierarchy_file, "hierarchy"],
  16. [split_file, "_split"],
  17. [parts_file, "_part_locs"],
  18. ]
  19. def _path(self, file):
  20. return join(self.root, file)
  21. def _open(self, file):
  22. return open(self._path(file))
  23. def read_content(self, file, attr):
  24. content = None
  25. if isfile(self._path(file)):
  26. with self._open(file) as f:
  27. content = [line.strip() for line in f if line.strip()]
  28. setattr(self, attr, content)
  29. def __init__(self, root):
  30. super(Annotations, self).__init__()
  31. self.root = root
  32. for fname, attr in Annotations.meta.structure:
  33. self.read_content(fname, attr)
  34. self.labels = np.array([int(l) for l in self.labels], dtype=np.int32)
  35. self._load_uuids()
  36. self._load_parts()
  37. self._load_split()
  38. def _load_uuids(self):
  39. assert self._images is not None, "Images were not loaded!"
  40. uuid_fnames = [i.split() for i in self._images]
  41. self.uuids, self.images = map(np.array, zip(*uuid_fnames))
  42. self.uuid_to_idx = {uuid: i for i, uuid in enumerate(self.uuids)}
  43. def _load_parts(self):
  44. assert self._part_locs is not None, "Part locations were not loaded!"
  45. # this part is quite slow... TODO: some runtime improvements?
  46. uuid_to_parts = defaultdict(list)
  47. for content in [i.split() for i in self._part_locs]:
  48. uuid_to_parts[content[0]].append([int(i) for i in content[1:]])
  49. self.part_locs = np.stack([uuid_to_parts[uuid] for uuid in self.uuids])
  50. def _load_split(self):
  51. assert self._split is not None, "Train-test split was not loaded!"
  52. uuid_to_split = {uuid: int(split) for uuid, split in [i.split() for i in self._split]}
  53. self.train_split = np.array([uuid_to_split[uuid] for uuid in self.uuids], dtype=bool)
  54. self.test_split = np.logical_not(self.train_split)
  55. def image_path(self, image):
  56. return join(self.root, Annotations.meta.images_folder, image)
  57. def image(self, uuid):
  58. fname = self.images[self.uuid_to_idx[uuid]]
  59. return self.image_path(fname)
  60. def label(self, uuid):
  61. return self.labels[self.uuid_to_idx[uuid]]
  62. def parts(self, uuid):
  63. return self.part_locs[self.uuid_to_idx[uuid]]
  64. def _uuids(self, split):
  65. return self.uuids[split]
  66. # for i in np.where(split)[0]:
  67. # uuid = self.image_list[i]
  68. # yield uuid
  69. @property
  70. def train_uuids(self):
  71. return self._uuids(self.train_split)
  72. @property
  73. def test_uuids(self):
  74. return self._uuids(self.test_split)