|
@@ -7,12 +7,7 @@ from abc import ABC, abstractmethod, abstractproperty
|
|
|
|
|
|
from . import utils
|
|
|
|
|
|
-class Parts(object):
|
|
|
-
|
|
|
- def __init__(self, image, part_annotations, rescale_size):
|
|
|
- super(Parts, self).__init__()
|
|
|
-
|
|
|
- self._parts = [BasePart.new(image, a, rescale_size) for a in part_annotations]
|
|
|
+class BaseParts(ABC):
|
|
|
|
|
|
def __getitem__(self, i):
|
|
|
return self._parts[i]
|
|
@@ -65,6 +60,36 @@ class Parts(object):
|
|
|
|
|
|
return res
|
|
|
|
|
|
+class Parts(BaseParts):
|
|
|
+
|
|
|
+ def __init__(self, image, part_annotations, rescale_size):
|
|
|
+ super(Parts, self).__init__()
|
|
|
+ self._parts = [BasePart.new(image, a, rescale_size) for a in part_annotations]
|
|
|
+
|
|
|
+
|
|
|
+class UniformParts(BaseParts):
|
|
|
+
|
|
|
+ def __init__(self, image, ratio):
|
|
|
+ super(UniformParts, self).__init__()
|
|
|
+ self._parts = list(self.generate_parts(image, ratio))
|
|
|
+
|
|
|
+ def generate_parts(self, im, ratio, round_op=np.floor):
|
|
|
+ h, w, c = utils.dimensions(im)
|
|
|
+
|
|
|
+ part_w = round_op(w * ratio).astype(np.int32)
|
|
|
+ part_h = round_op(h * ratio).astype(np.int32)
|
|
|
+
|
|
|
+ n, m = w // part_w, h // part_h
|
|
|
+
|
|
|
+ # fit best possible part_w and part_h
|
|
|
+ part_w = int(w / n)
|
|
|
+ part_h = int(h / m)
|
|
|
+
|
|
|
+ for i in range(n*m):
|
|
|
+ row, col = np.unravel_index(i, (n, m))
|
|
|
+ x, y = col * part_w, row * part_h
|
|
|
+
|
|
|
+ yield BBoxPart(im, [i, x, y, part_w, part_h])
|
|
|
|
|
|
class BasePart(ABC):
|
|
|
|
|
@@ -100,6 +125,9 @@ class BasePart(ABC):
|
|
|
return np.array([self.x, self.y])
|
|
|
|
|
|
def crop(self, im, w, h, padding_mode="edge", is_location=True):
|
|
|
+ if not self.is_visible:
|
|
|
+ _, _, c = utils.dimensions(im)
|
|
|
+ return np.zeros((h, w, c), dtype=np.uint8)
|
|
|
|
|
|
x, y = self.xy
|
|
|
pad_h, pad_w = h // 2, w // 2
|
|
@@ -119,7 +147,7 @@ class BasePart(ABC):
|
|
|
class LocationPart(BasePart):
|
|
|
DEFAULT_RATIO = np.sqrt(49 / 400) # 0.35
|
|
|
|
|
|
- def __init__(self, image, annotation, rescale_size):
|
|
|
+ def __init__(self, image, annotation, rescale_size=None):
|
|
|
super(LocationPart, self).__init__()
|
|
|
|
|
|
annotation = self.rescale(image, annotation, rescale_size)
|
|
@@ -131,11 +159,7 @@ class LocationPart(BasePart):
|
|
|
ratio = ratio or self._ratio
|
|
|
_h, _w, c = utils.dimensions(image)
|
|
|
w, h = int(_w * ratio), int(_h * ratio)
|
|
|
-
|
|
|
- if not self.is_visible:
|
|
|
- return np.zeros((h, w, c), dtype=np.uint8)
|
|
|
- else:
|
|
|
- return super(LocationPart, self).crop(image, w, h,
|
|
|
+ return super(LocationPart, self).crop(image, w, h,
|
|
|
padding_mode, is_location=True)
|
|
|
|
|
|
def reveal(self, im, ratio=None, *args, **kwargs):
|
|
@@ -159,7 +183,7 @@ class LocationPart(BasePart):
|
|
|
|
|
|
class BBoxPart(BasePart):
|
|
|
|
|
|
- def __init__(self, image, annotation, rescale_size):
|
|
|
+ def __init__(self, image, annotation, rescale_size=None):
|
|
|
super(BBoxPart, self).__init__()
|
|
|
|
|
|
annotation = self.rescale(image, annotation, rescale_size)
|