part.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import numpy as np
  2. from . import utils
  3. class Parts(object):
  4. def __init__(self, image, part_annotations, rescale_size):
  5. super(Parts, self).__init__()
  6. annots = utils.rescale_parts(image, part_annotations, rescale_size)
  7. self._parts = [ImagePart(image, a) for a in annots]
  8. self.rescale_size = rescale_size
  9. def __getitem__(self, i):
  10. return self._parts[i]
  11. @property
  12. def selected(self):
  13. return np.array([p.is_visible for p in self._parts], dtype=bool)
  14. @property
  15. def selected_idxs(self):
  16. return np.where(self.selected)[0]
  17. def select(self, idxs):
  18. if isinstance(idxs, np.ndarray) and idxs.dtype == bool:
  19. # a mask is present, so convert it to indeces
  20. idxs = np.where(idxs)[0]
  21. for p in self._parts:
  22. p.is_visible = p._id in idxs
  23. def invert_selection(self):
  24. self.select(np.logical_not(self.selected))
  25. def set_visibility(self, idxs, value):
  26. for p in self._parts[idxs]:
  27. p.is_visible = value
  28. def visible_locs(self):
  29. vis = [(p._id, p.xy) for p in self._parts if p.is_visible]
  30. idxs, xy = zip(*vis)
  31. return np.array(idxs), np.array(xy).T
  32. def visible_crops(self, *args, **kwargs):
  33. return np.array([p.crop(*args, **kwargs) for p in self._parts])
  34. class ImagePart(object):
  35. def __init__(self, image, annotation):
  36. super(ImagePart, self).__init__()
  37. self.image = image
  38. if len(annotation) == 4:
  39. # here x,y are the center of the part
  40. self._id, self.x, self.y, self._is_visible = annotation
  41. self.w, self.h = None, None
  42. elif len(annotation) == 5:
  43. # here x,y are top left corner of the part
  44. self._id, self.x, self.y, self.w, self.h = annotation
  45. self._is_visible = True
  46. else:
  47. raise ValueError("Unknown annotation format: {}".format(annotation))
  48. def crop(self, ratio=None, padding_mode="edge"):
  49. if not self.is_visible:
  50. h, w, c = utils.dimensions(self.image)
  51. crop_h, crop_w = int(h * ratio), int(w * ratio)
  52. return np.zeros((crop_h, crop_w, c), dtype=np.uint8)
  53. else:
  54. return utils.crop(self.image, self.xy, ratio, padding_mode)
  55. @property
  56. def is_visible(self):
  57. return bool(self._is_visible)
  58. @is_visible.setter
  59. def is_visible(self, value):
  60. self._is_visible = bool(value)
  61. @property
  62. def xy(self):
  63. return np.array([self.x, self.y])
  64. @property
  65. def wh(self):
  66. return np.array([self.w, self.h])