def get(self, image, sigma, alpha, ignore_last_dim, **kwargs): shape = image.shape if ignore_last_dim: shape = shape[:-1] deltas = [] ranges = [] coordinates = [] for dim in shape: deltas.append( gaussian_filter( (np.random.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0 ) * alpha ) ranges.append(np.arange(dim)) grids = list(np.meshgrid(*ranges)) for grid, delta in zip(grids, deltas): dDim = np.transpose(grid, axes=(1, 0) + tuple(range(2, grid.ndim))) + delta coordinates.append(np.reshape(dDim, (-1, 1))) if ignore_last_dim: for z in range(image.shape[-1]): image[..., z] = utils.safe_call( map_coordinates, input=image[..., z], coordinates=coordinates, **kwargs ).reshape(shape) else: image = utils.safe_call( map_coordinates, input=image, coordinates=coordinates, **kwargs ).reshape(shape) # TODO: implement interpolated coordinate mapping for property positions # for prop in image: # if "position" in prop: return image
def get(self, image, ksize, **kwargs): kwargs.pop("func", False) kwargs.pop("image", False) kwargs.pop("block_size", False) return utils.safe_call(skimage.measure.block_reduce, image=image, func=self.pooling, block_size=ksize, **kwargs)
def get(self, image, px, **kwargs): padding = [] if isinstance(px, int): padding = [(px, px)] * image.ndom for idx in range(0, len(px), 2): padding.append((px[idx], px[idx + 1])) while len(padding) < image.ndim: padding.append((0, 0)) return utils.safe_call(np.pad, positional_args=(image, padding), **kwargs) # TODO: add resizing by rescaling
def get(self, image, scale, translate, rotate, shear, **kwargs): assert ( image.ndim == 2 or image.ndim == 3 ), "Affine only supports 2-dimensional or 3-dimension inputs." dx, dy = translate fx, fy = scale cr = np.cos(rotate) sr = np.sin(rotate) k = np.tan(shear) scale_map = np.array([[1 / fx, 0], [0, 1 / fy]]) rotation_map = np.array([[cr, sr], [-sr, cr]]) shear_map = np.array([[1, 0], [-k, 1]]) mapping = scale_map @ rotation_map @ shear_map shape = image.shape center = np.array(shape[:2]) / 2 d = center - np.dot(mapping, center) - np.array([dy, dx]) # Clean up kwargs kwargs.pop("input", False) kwargs.pop("matrix", False) kwargs.pop("offset", False) kwargs.pop("output", False) # Call affine_transform if image.ndim == 2: new_image = utils.safe_call( ndimage.affine_transform, input=image, matrix=mapping, offset=d, **kwargs ) new_image = Image(new_image) new_image.merge_properties_from(image) image = new_image elif image.ndim == 3: for z in range(shape[-1]): image[:, :, z] = utils.safe_call( ndimage.affine_transform, input=image[:, :, z], matrix=mapping, offset=d, **kwargs ) # Map positions inverse_mapping = np.linalg.inv(mapping) for prop in image.properties: if "position" in prop: position = np.array(prop["position"]) prop["position"] = np.array( ( *( ( inverse_mapping @ (position[:2] - center + np.array([dy, dx])) + center ) ), *position[3:], ) ) return image
def get(self, image, **kwargs): kwargs.pop("src", False) kwargs.pop("dst", False) utils.safe_call(self.filter, src=image, dst=image, **kwargs) return image
def get(self, image, **kwargs): kwargs.pop("input", False) return utils.safe_call(self.filter, input=image, **kwargs)
def test_safe_call(self): arguments = { "key1": None, "key2": False, "key_not_in_function": True, "key_not_in_function_2": True, } def func1(): pass utils.safe_call(func1, **arguments) def func2(key1): pass utils.safe_call(func2, **arguments) def func3(key1, key2=2): pass utils.safe_call(func3, **arguments) def func4(key1, *argv, key2=2): pass self.assertRaises(TypeError, lambda: utils.safe_call(func4, **arguments)) def func5(*argv, key1, key2=2): pass utils.safe_call(func5, **arguments) def func6(key1, key2=1, key3=3, **kwargs): pass utils.safe_call(func6, **arguments)