import numpy as np from PIL.Image import Image as PIL_Image DEFAULT_RATIO = np.sqrt(49 / 400) def dimensions(im): if isinstance(im, np.ndarray): if im.ndim != 3: import pdb; pdb.set_trace() assert im.ndim == 3, "Only RGB images are currently supported!" return im.shape elif isinstance(im, PIL_Image): w, h = im.size c = len(im.getbands()) # assert c == 3, "Only RGB images are currently supported!" return h, w, c else: raise ValueError("Unknown image instance ({})!".format(type(im))) def asarray(im, dtype=np.uint8): if isinstance(im, np.ndarray): return im.astype(dtype) elif isinstance(im, PIL_Image): return np.asarray(im, dtype=dtype) else: raise ValueError("Unknown image instance ({})!".format(type(im))) def select_crops(crops, mask): selected = np.zeros_like(crops) selected[mask] = crops[mask] return selected def selection_mask(idxs, n): return np.bincount(idxs, minlength=n).astype(bool) def random_select(idxs, xy, part_crops, *args, **kw): rnd_idxs = random_idxs(np.arange(len(idxs)), *args, **kw) idxs = idxs[rnd_idxs] xy = xy[:, rnd_idxs] mask = selection_mask(idxs, len(part_crops)) selected_crops = select_crops(part_crops, mask) return idxs, xy, selected_crops def random_idxs(idxs, rnd=None, n_parts=None): if rnd is None or isinstance(rnd, int): rnd = np.random.RandomState(rnd) else: assert isinstance(rnd, np.random.RandomState), \ "'rnd' should be either a random seed or a RandomState instance!" n_parts = n_parts or rnd.randint(1, len(idxs)) res = rnd.choice(idxs, n_parts, replace=False) res.sort() return res ##### DEPRECATED ##### # def __expand_parts(p): # return p[:, 0], p[:, 1:3], p[:, 3].astype(bool) def uniform_parts(im, ratio=DEFAULT_RATIO, round_op=np.floor): raise DeprecationWarning("Do not use me!") # h, w, c = 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 # parts = np.ones((n*m, 4), dtype=int) # parts[:, 0] = np.arange(n*m) # for x in range(n): # for y in range(m): # i = y * n + x # x0, y0 = x * part_w, y * part_h # parts[i, 1:3] = [x0 + part_w // 2, y0 + part_h // 2] # return parts def rescale_parts(im, parts, part_rescale_size): raise DeprecationWarning("Do not use me!") # if part_rescale_size is None or part_rescale_size < 0: # return parts # h, w, c = dimensions(im) # scale = np.array([w, h]) / part_rescale_size # xy = parts[:, 1:3] # xy = xy * scale # parts[:, 1:3] = xy # if parts.shape[1] == 5: # wh = parts[:, 3:5] # wh = wh * scale # parts[:, 3:5] = wh # return parts def visible_part_locs(p): raise DeprecationWarning("Do not use me!") # res = p.visible_locs() # return res # idxs, locs, vis = __expand_parts(p) # return idxs[vis], locs[vis].T def crop(im, xy, w, h, padding_mode="edge", is_location=True): raise DeprecationWarning("Do not use me!") # x, y = xy # pad_h, pad_w = h // 2, w // 2 # padded_im = np.pad(im, [(pad_h, pad_h), (pad_w, pad_w), [0,0]], mode=padding_mode) # x0, y0 = x + pad_w, y + pad_h # if is_location: # x0, y0 = x0 - w // 2, y0 - h // 2 # return padded_im[y0:y0+h, x0:x0+w] def crops(im, xys, ratio=DEFAULT_RATIO, padding_mode="edge"): raise DeprecationWarning("Do not use me!") # h, w, c = dimensions(im) # crop_h, crop_w = int(h * ratio), int(w * ratio) # return np.stack([crop(im, xy, crop_w, crop_h, padding_mode) # for xy in xys.T]) def visible_crops(im, p, *args, **kw): raise DeprecationWarning("Do not use me!") # res = p.visible_crops(*args, **kw) # return res # idxs, locs, vis = __expand_parts(p) # parts = crops(asarray(im), locs[vis].T, *args, **kw) # res = np.zeros((len(idxs),) + parts.shape[1:], dtype=parts.dtype) # res[vis] = parts # return res def reveal_parts(im, xy, ratio=DEFAULT_RATIO): raise DeprecationWarning("Do not use me!") # h, w, c = dimensions(im) # crop_h, crop_w = int(h * ratio), int(w * ratio) # im = asarray(im) # res = np.zeros_like(im) # for x, y in xy.T: # x0, y0 = max(x - crop_w // 2, 0), max(y - crop_h // 2, 0) # res[y0:y0+crop_h, x0:x0+crop_w] = im[y0:y0+crop_h, x0:x0+crop_w] # return res