def __call__(self, image: np.ndarray, seed) -> np.ndarray: """ Expect numpy ndarrays with color in the last channel of the array [x,y,z,c] or , [x,y,c] Performs random elastic deformations to the image :param image: :return: """ if not isinstance(image, np.ndarray): raise ValueError( f'Expected input to be numpy.ndarray but got {type(image)}') dtype = image.dtype np.random.seed(seed) if image.ndim == 4: # generate a deformation grid if self.z_grid is not None: displacement = np.random.randn(3, self.x_grid, self.y_grid, self.z_grid) * self.scale else: raise ValueError( 'Misspecified deformation vector shape. Should look like: tuple (X, Y, Z)' ) if image.shape[-1] > 1: image = elasticdeform.deform_grid(image, displacement, axis=(0, 1, 2)) # Try to detect if its the mask. Then just dont interpalate. elif image.shape[-1] == 1: image = elasticdeform.deform_grid(image, displacement, axis=(0, 1, 2), order=0) else: raise ValueError('Dun F****d Uterp') image[image < 0] = 0 image[image > 1] = 1 image.astype(dtype) elif image.ndim == 3: # generate a deformation grid displacement = np.random.randn(2, self.x_grid, self.y_grid) * self.scale image = elasticdeform.deform_grid(image, displacement, axis=(0, 1)) else: raise ValueError(f'Expected np.ndarray with 3 or 4 dimmensions, ' f'NOT dim: {image.ndim}, shape: {image.shape}') return image
def run_comparison_torch(self, shape, points, order=3, sigma=25, crop=None, mode='constant', axis=None): if torch is None: raise unittest.SkipTest("PyTorch was not loaded.") # generate random displacement vector displacement = np.random.randn(len(shape) if axis is None else len(axis), *points) * sigma # generate random data X_val = np.random.rand(*shape) # compute forward reference value X_deformed_ref = elasticdeform.deform_grid(X_val, displacement, order=order, crop=crop, mode=mode, axis=axis) # generate gradient dX_deformed_val = np.random.rand(*X_deformed_ref.shape) # compute backward reference value dX_ref = elasticdeform.deform_grid_gradient(dX_deformed_val, displacement, order=order, crop=crop, mode=mode, axis=axis, X_shape=shape) # compute PyTorch output X = torch.tensor(X_val, requires_grad=True) displacement = torch.tensor(displacement) dX_deformed = torch.tensor(dX_deformed_val) X_deformed = etorch.deform_grid(X, displacement, order=order, crop=crop, mode=mode, axis=axis) X_deformed.backward(dX_deformed) dX = X.grad # convert back to numpy X_deformed = X_deformed.detach().numpy() dX = dX.detach().numpy() np.testing.assert_almost_equal(X_deformed_ref, X_deformed) np.testing.assert_almost_equal(dX_ref, dX)
def elastic_bbox(X,bbox,displacement,order=3,mode='constant', cval=0.0, crop=None, prefilter=True,bbox_mode = 'rotated'): ''' if isinstance(X, numpy.ndarray): Xs = [X] elif isinstance(X, list): Xs = X else: raise Exception('X should be a numpy.ndarray or a list of numpy.ndarrays.') assert len(Xs) > 0, 'You must provide at least one image.' assert all(isinstance(x, numpy.ndarray) for x in Xs), 'All elements of X should be numpy.ndarrays.' ''' #create a mask and apply transformation on the mask mask = np.zeros(X.shape[:2],dtype = 'uint8') (x,y,w,h) = bbox cv2.rectangle(mask,(x,y),(x+w,y+h),255,-1) mask = elasticdeform.deform_grid(mask,displacement,axis = (0,1)) #calculate mean intensity outside of mask constant_intensity = np.mean(X[:y,:x,:],axis = (0,1)) ret,thresh = cv2.threshold(mask,127,255,0) contours = cv2.findContours(thresh, mode=1,method=2) cnt = contours[0] if bbox_mode == 'rotated': rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) # four courners #box = np.int0(box) return box else: x,y,w,h = cv2.boundingRect(cnt) #width and height return (x,y,w,h),constant_intensity
def elastic_deform(self, img, mask, sigma, points): disp_grid = self.random_displacement_grid(img, sigma, points, axis=(0, 1, 2)) # [img, mask] = deform_random_grid( # [img, mask], sigma=sigma, points=points, axis=[(0, 1, 2), (0, 1, 2)], order=order) img = deform_grid(img, disp_grid, axis=(0, 1, 2), order=3) mask = deform_grid(mask, disp_grid, axis=(0, 1, 2), order=0) # if self.categorical: # mask = round_mask(mask) # else: # mask = round_mask_semantic(mask) return img, mask
def __call__(self, img): if self.prob: if np.random.uniform() >= 0.5: res = img return res if 'complex' == img.dtype: res_real = elasticdeform.deform_grid( img.real, displacement=self.displacement, mode=self.mode) res_img = elasticdeform.deform_grid(img.imag, displacement=self.displacement, mode=self.mode) res = res_real + 1j * res_img else: res = elasticdeform.deform_grid(img, displacement=self.displacement, mode=self.mode) return res
def forward(ctx, displacement, deform_args, deform_kwargs, *xs): ctx.save_for_backward(displacement) ctx.deform_args = deform_args ctx.deform_kwargs = deform_kwargs ctx.x_shapes = [x.shape for x in xs] xs_numpy = [x.detach().cpu().numpy() for x in xs] displacement = displacement.detach().cpu().numpy() ys = elasticdeform.deform_grid(xs_numpy, displacement, *deform_args, **deform_kwargs) return tuple(torch.tensor(y, device=x.device) for x, y in zip(xs, ys))
def deform_grid_c(X_in, displacement, order=3, mode='constant', cval=0.0, crop=None, prefilter=True, axis=None): return elasticdeform.deform_grid(X_in, displacement, order, mode, cval, crop, prefilter, axis)
def run_comparison_tensorflow(self, shape, points, order=3, sigma=25, crop=None, mode='constant', axis=None): if tf is None or not hasattr(tf, 'py_func'): raise unittest.SkipTest("TensorFlow 1 was not loaded.") # generate random displacement vector displacement = np.random.randn( len(shape) if axis is None else len(axis), *points) * sigma # generate random data X_val = np.random.rand(*shape) # compute forward reference value X_deformed_ref = elasticdeform.deform_grid(X_val, displacement, order=order, crop=crop, mode=mode, axis=axis) # generate gradient dY_val = np.random.rand(*X_deformed_ref.shape) # compute backward reference value dX_ref = elasticdeform.deform_grid_gradient(dY_val, displacement, order=order, crop=crop, mode=mode, axis=axis, X_shape=shape) # build tensorflow graph X = tf.Variable(X_val) dY = tf.Variable(dY_val) X_deformed = etf.deform_grid(X, displacement, order=order, crop=crop, mode=mode, axis=axis) [dX] = tf.gradients(X_deformed, X, dY) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) X_deformed_val, dX_val = sess.run([X_deformed, dX]) np.testing.assert_almost_equal(X_deformed_ref, X_deformed_val) np.testing.assert_almost_equal(dX_ref, dX_val)
def random_elastic_bbox(X,bbox,sigma=25,points=3,mode='constant',cval=0.0,crop=None,prefilter=True,bbox_mode='rotated'): #random displacement if not isinstance(biboxes,list): bboxes = [bboxes] if not isinstance(points,(list,tuple)): points = [points] * 2 displacement = np.random.randn(2,*points) * sigma #displaced_image = elasticdeform.deform_grid(X, displacement, order = 3, mode = 'constant', cval = 0.0, crop=None, prefilter = True,axis=(0,1)) displaced_bbox,constant_intensity = elastic_bbox(X,bbox,displacement,bbox_mode=bbox_mode) displaced_image = elasticdeform.deform_grid(X,displacement, order = 3,mode = 'constant',cval = 0.0,axis=(0,1)) displaced_image[np.sum(displaced_image,axis = (0,1)) == 0,:] = constant_intensity return (displaced_image,displaced_bbox)
def elDeform(self,seedN, seedn, image): if self.elasticDeformation==True: np.random.seed(seedn) if np.random.random() < self.apply_deformation: np.random.seed(seedN) displacement = np.random.randn(2, self.controlPoints1, self.controlPoints2) * self.elasticDeformationScale converted_img = elasticdeform.deform_grid(image, displacement,axis=(0, 1), mode = 'nearest') else: converted_img = image else: converted_img=image #print('converted_img.shape: ',converted_img.shape) return converted_img
def deform(data): res = data.copy() points = [3, 3] displacement = (np.random.rand(2, *points) - 0.5) * 5 for k in range(0, ntheta): res[k] = elasticdeform.deform_grid(data[k].real, displacement, order=5, mode='mirror', crop=None, prefilter=True, axis=None) return res
def elDeform(self, seedN, image): if self.elasticDeformation == True: np.random.seed(seedN) displacement = np.random.randn( 2, self.controlPoints1, self.controlPoints2) * self.elasticDeformationScale converted_img = elasticdeform.deform_grid(image, displacement, axis=(0, 1)) else: converted_img = image print('converted_img.shape: ', converted_img.shape) return converted_img
def deform_data(u, theta, displacement0, k): """Deform object with respect to displacement0*(1-exp(t[k])) displacement, and computes its projection data""" print('deforming 3d frame', k) [nz, ne] = u.shape[:2] displacement = displacement0 * (1 - np.exp(np.linspace(0, 1, len(theta))[k])) ud = elasticdeform.deform_grid(u, displacement, order=1, mode='mirror', crop=None, prefilter=True, axis=None) with SolverTomo(theta[k:k + 1], 1, nz, ne, 32, ne / 2, 1) as tslv: data = tslv.fwd_tomo_batch(ud) return data
def _elastic_transform(x, seed: uniform_int = 42, sigma=8, points=5, interpolation_magnitude=1, mode="mirror"): ''' Slightly altered elastic smooth deformation based on following repo: https://pypi.org/project/elasticdeform/ :seed: random factor for np.random, uniform_int range for random seeding (int) :sigma: standard deviation of the normal distribution (float) :points: number of points in displacement grid -> points * points (int) :interpolation_magnitude: magnitude of interpolation, no interpolation if 0 ({0, 1, 2, 3, 4}) :mode: border mode (({nearest, wrap, reflect, mirror, constant})) ''' image_array = np.asarray(x.data)[0] cval = 0.0 prefilter = True axis = None if mode == "constant": cval = np.unique(image_array)[0] # prepare inputs and axis selection Xs = _normalize_inputs(image_array) axis, deform_shape = _normalize_axis_list(axis, Xs) if not isinstance(points, (list, tuple)): points = [points] * len(deform_shape) np.random.seed(seed=seed) displacement = np.random.randn(len(deform_shape), *points) * sigma image_array = elasticdeform.deform_grid(image_array, displacement=displacement, order=interpolation_magnitude, mode=mode, cval=cval, prefilter=prefilter, axis=axis) return pil2tensor(image_array, np.float32)
def run_comparison_tensorflow_multi(self, shape, points, order=3, sigma=25, crop=None, mode='constant', axis=None): if tf is None or not hasattr(tf, 'py_function') or hasattr(tf, 'py_func'): raise unittest.SkipTest("TensorFlow 2 was not loaded.") # generate random displacement vector displacement = np.random.randn(len(shape) if axis is None else len(axis), *points) * sigma # generate random data X_val = np.random.rand(*shape) # generate more random data Y_val = np.random.rand(*shape) # compute forward reference value X_deformed_ref, Y_deformed_ref = elasticdeform.deform_grid([X_val, Y_val], displacement, order=order, crop=crop, mode=mode, axis=axis) # generate gradient dX_deformed_val = np.random.rand(*X_deformed_ref.shape) dY_deformed_val = np.random.rand(*Y_deformed_ref.shape) # compute backward reference value dX_ref, dY_ref = elasticdeform.deform_grid_gradient([dX_deformed_val, dY_deformed_val], displacement, order=order, crop=crop, mode=mode, axis=axis, X_shape=[shape, shape]) # compute tensorflow output X = tf.Variable(X_val) Y = tf.Variable(Y_val) dX_deformed = tf.Variable(dX_deformed_val) dY_deformed = tf.Variable(dY_deformed_val) with tf.GradientTape(persistent=True) as g: g.watch(X) g.watch(Y) X_deformed, Y_deformed = etf.deform_grid([X, Y], displacement, order=order, crop=crop, mode=mode, axis=axis) dX = g.gradient(X_deformed, X, dX_deformed) dY = g.gradient(Y_deformed, Y, dY_deformed) np.testing.assert_almost_equal(X_deformed_ref, X_deformed) np.testing.assert_almost_equal(Y_deformed_ref, Y_deformed) np.testing.assert_almost_equal(dX_ref, dX) np.testing.assert_almost_equal(dY_ref, dY)
def fwd(displacement, *xs): if not use_tf_v1: xs = [x.numpy() for x in list(xs)] displacement = displacement.numpy() return elasticdeform.deform_grid(list(xs), displacement, *args, **kwargs)
def fwd(displacement, *xs): return elasticdeform.deform_grid(list(xs), displacement, *args, **kwargs)