def _deformation_grid(self): """ Get a new random deformation grid :return: deformation tensor """ sigma = np.random.rand() * self.sigma displacement = np.random.randn(*self.points, 2) * sigma # filter the displacement displacement_f = np.zeros_like(displacement) for d in range(0, displacement.ndim - 1): spline_filter1d(displacement, axis=d, order=3, output=displacement_f, mode='nearest') displacement = displacement_f # resample to proper size displacement_f = np.zeros((self.shape[0], self.shape[1], self.shape[2], 2)) for d in range(0, displacement.ndim - 1): displacement_f[:, :, :, d] = cv2.resize(displacement[:, :, :, d], dsize=self.shape, interpolation=cv2.INTER_CUBIC) displacement = torch.Tensor(displacement_f).unsqueeze(0) if self.cuda: displacement = displacement.cuda() grid = self.grid + displacement return grid
def test_spline_filter_vs_matrix_solution(order): n = 100 eye = np.eye(n, dtype=float) spline_filter_axis_0 = ndimage.spline_filter1d(eye, axis=0, order=order) spline_filter_axis_1 = ndimage.spline_filter1d(eye, axis=1, order=order) matrix = make_spline_knot_matrix(n, order) assert_almost_equal(eye, np.dot(spline_filter_axis_0, matrix)) assert_almost_equal(eye, np.dot(spline_filter_axis_1, matrix.T))
def test_spline_filter_vs_matrix_solution(order): n = 100 eye = np.eye(n, dtype=float) spline_filter_axis_0 = ndimage.spline_filter1d(eye, axis=0, order=order) spline_filter_axis_1 = ndimage.spline_filter1d(eye, axis=1, order=order) matrix = make_spline_knot_matrix(n, order) assert_almost_equal(eye, np.dot(spline_filter_axis_0, matrix)) assert_almost_equal(eye, np.dot(spline_filter_axis_1, matrix.T))
def image_process(data, mode="gaussian", sigma=2.5, order=0, weight=None, weightMtxSize=7, convMode="constant", cval=0.0, splineOrder=1.0): if mode == "convolve": # if weight is None, create a weight matrix if weight is None: weight = np.ones((weightMtxSize, weightMtxSize)) center = (weightMtxSize - 1) / 2 for i in range(-(center), center + 1, 1): for j in range(-(center), center + 1, 1): weight[i][j] /= math.pow(2.0, max(abs(i), abs(j))) return ndimage.convolve(data, weight, mode=convMode, cval=cval) elif mode == "fourier_gaussian": return ndimage.fourier_gaussian(data, sigma=sigma) elif mode == "spline": return ndimage.spline_filter1d(data, order=splineOrder) else: if mode != "gaussian": print "apply Gaussian filter in image_process()" return ndimage.gaussian_filter(data, sigma=sigma, order=order)
def smooth(self, idata, mode, **kwargs): """Smooth data for contour() and contourf() idata is smoothed by convolve, fourier_gaussian, spline or gaussian (default). If contour_mode is 'convolve' and weight is None, the weight matrix is created automatically. Parameters ----------- idata : numpy 2D array Input data mode : string 'convolve','fourier','spline' or 'gaussian' Returns --------- odata : numpy 2D array See also ---------- http://docs.scipy.org/doc/scipy/reference/ndimage.html """ # modify default parameter self._set_defaults(kwargs) if mode == 'convolve': # if weight is None, create a weight matrix if self.convolve_weights is None: weights = np.ones( (self.convolve_weightSize, self.convolve_weightSize)) center = int((self.convolve_weightSize - 1) / 2) for i in range(-(center), center + 1, 1): for j in range(-(center), center + 1, 1): weights[i][j] /= pow(2.0, max(abs(i), abs(j))) self.convolve_weights = weights odata = ndimage.convolve(idata, weights=self.convolve_weights, mode=self.convolve_mode, cval=self.convolve_cval, origin=self.convolve_origin) elif mode == 'fourier': odata = ndimage.fourier_gaussian(idata, sigma=self.fourier_sigma, n=self.fourier_n, axis=self.fourier_axis) elif mode == 'spline': odata = ndimage.spline_filter1d(idata, order=self.spline_order, axis=self.spline_axis) else: if mode != 'gaussian': print('apply Gaussian filter in image_process()') odata = ndimage.gaussian_filter(idata, sigma=self.gaussian_sigma, order=self.gaussian_order, mode=self.gaussian_mode, cval=self.gaussian_cval) return odata
def smooth(self, idata, mode, **kwargs): '''Smooth data for contour() and contourf() idata is smoothed by convolve, fourier_gaussian, spline or gaussian (default). If contour_mode is 'convolve' and weight is None, the weight matrix is created automatically. Parameters ----------- idata : numpy 2D array Input data mode : string 'convolve','fourier','spline' or 'gaussian' Returns --------- odata : numpy 2D array See also ---------- http://docs.scipy.org/doc/scipy/reference/ndimage.html ''' # modify default parameter self._set_defaults(kwargs) if mode == 'convolve': # if weight is None, create a weight matrix if self.convolve_weights is None: weights = np.ones((self.convolve_weightSize, self.convolve_weightSize)) center = (self.convolve_weightSize - 1) / 2 for i in range(- (center), center + 1, 1): for j in range(- (center), center + 1, 1): weights[i][j] /= pow(2.0, max(abs(i), abs(j))) self.convolve_weights = weights odata = ndimage.convolve(idata, weights=self.convolve_weights, mode=self.convolve_mode, cval=self.convolve_cval, origin=self.convolve_origin) elif mode == 'fourier': odata = ndimage.fourier_gaussian(idata, sigma=self.fourier_sigma, n=self.fourier_n, axis=self.fourier_axis) elif mode == 'spline': odata = ndimage.spline_filter1d(idata, order=self.spline_order, axis=self.spline_axis) else: if mode != 'gaussian': print 'apply Gaussian filter in image_process()' odata = ndimage.gaussian_filter(idata, sigma=self.gaussian_sigma, order=self.gaussian_order, mode=self.gaussian_mode, cval=self.gaussian_cval) return odata
def image_process(data, mode="gaussian", sigma=2.5, order=0, weight=None, weightMtxSize=7, convMode="constant", cval=0.0, splineOrder=1.0): if mode=="convolve": # if weight is None, create a weight matrix if weight is None: weight = np.ones((weightMtxSize, weightMtxSize)) center = (weightMtxSize - 1) / 2 for i in range(-(center), center+1, 1): for j in range(-(center), center+1, 1): weight[i][j] /= math.pow(2.0, max(abs(i),abs(j))) return ndimage.convolve(data, weight, mode=convMode, cval=cval) elif mode=="fourier_gaussian": return ndimage.fourier_gaussian(data, sigma=sigma) elif mode=="spline": return ndimage.spline_filter1d(data, order=splineOrder) else: if mode!="gaussian": print "apply Gaussian filter in image_process()" return ndimage.gaussian_filter(data, sigma=sigma, order=order)
def opt(obj, psf, theta=None, pad=False): """ Simulate the OPT imaging of an object Parameters ---------- obj : array [ZXY] the object to be imaged, ZX must be square psf : array [ZXY] the PSF of the imaging system, Z dimension must match object ZX theta : array, optional array of rotation angles (in degrees), by default None If None, uses numpy.arange(180). pad : bool, optional extend the field of view to see all contributions (needed if the object is not contained in the inner cylinder to the array), by default False Returns ------- array [TPY] the imaged sinogram Raises ------ ValueError if the PSF dimension does not match the object """ if not obj.shape[0] == obj.shape[1]: raise NotImplementedError( 'Please provide a square object in ZX dimensions') if psf.shape[0] % 2 != obj.shape[0] % 2: raise ValueError( 'In order to correctly center the PSF,' ' please profide a PSF with the same Z axis parity as the object Z axis' ) if theta is None: theta = np.arange(180) full_size = obj.shape[0] if pad: full_size = int(full_size * np.sqrt(2)) + 1 pad_size = (full_size - obj.shape[0]) // 2 full_size = obj.shape[0] + 2 * pad_size if psf.shape[0] < full_size: raise ValueError( 'PSF Z size must be greater than padded object Z size: {} >= {}'. format(psf.shape[0], full_size)) if pad and pad_size: obj = np.pad(obj, ((pad_size, ), (pad_size, ), (0, ))) if pad: mode = 'full' sinogram = np.empty((theta.size, obj.shape[0] + psf.shape[1] - 1, obj.shape[-1] + psf.shape[-1] - 1)) else: mode = 'same' sinogram = np.empty((theta.size, obj.shape[0], obj.shape[-1])) splimage = ndimage.spline_filter1d(obj, axis=0) splimage = ndimage.spline_filter1d(obj, axis=1, output=splimage) crop_size = (psf.shape[0] - obj.shape[0]) // 2 if crop_size: psf = psf[crop_size:-crop_size, ...] psf = np.flip(psf, 0) for idx, angle in enumerate(theta): rotated = ndimage.rotate(splimage, angle, prefilter=False, reshape=False) rotated = sig.fftconvolve(rotated, psf, axes=(1, 2), mode=mode) sinogram[idx, ...] = rotated.sum(0) return sinogram
def to_spline(start, width): in_array = c[:, ..., start:start+width] out_array = output[:, ..., start:start+width] ndimage.spline_filter1d( in_array, degree, axis=0, mode=mode, output=out_array)
def convert_to_interpolation_coefficients(c, degree, tolerance=1e-9, boundary_condition='Mirror', in_place=False): """ Computes the b-spline interpolation coefficients of a signal In the input array, the signals are considered along the first dimension (1D computations). """ if degree == 0 or degree == 1 or c.shape[0] == 1: if not in_place: return c.copy() return c elif 2 <= degree <= 5: if boundary_condition.upper() == 'MIRROR': mode = 'mirror' elif boundary_condition.upper() == 'PERIODIC': mode = 'grid-wrap' else: raise ValueError( 'Invalid boundary condition: {}'.format(boundary_condition)) output = None if in_place: output = c if c.ndim < 2: output = ndimage.spline_filter1d( c, degree, axis=0, mode=mode, output=output) else: if output is None: output = np.empty_like(c) split_size = c.shape[-1] def to_spline(start, width): in_array = c[:, ..., start:start+width] out_array = output[:, ..., start:start+width] ndimage.spline_filter1d( in_array, degree, axis=0, mode=mode, output=out_array) parallel.parallelize(to_spline, split_size) return output if not in_place: c = c.copy() if degree == 6: z = [-0.488294589303044755130118038883789062112279161239377608394, -0.081679271076237512597937765737059080653379610398148178525368, -0.00141415180832581775108724397655859252786416905534669851652709] elif degree == 7: z = [-0.5352804307964381655424037816816460718339231523426924148812, -0.122554615192326690515272264359357343605486549427295558490763, -0.0091486948096082769285930216516478534156925639545994482648003] elif degree == 8: z = [-0.57468690924876543053013930412874542429066157804125211200188, -0.163035269297280935240551896860737052234768145508298548489731, -0.0236322946948448500234039192963613206126659208546294370651457, -0.000153821310641690911739352530184021607629640540700430019629940] elif degree == 9: z = [-0.60799738916862577900772082395428976943963471853990829550220, -0.201750520193153238796064685055970434680898865757470649318867, -0.043222608540481752133321142979429688265852380231497069381435, -0.00212130690318081842030489655784862342205485609886239466341517] elif degree == 10: z = [-0.63655066396942385875799205491349773313787959010128860432339, -0.238182798377573284887456162200161978666543494059728787251924, -0.065727033228308551538201803949684252205121694392255863103034, -0.0075281946755486906437698340318148831650567567441314086093636, -0.0000169827628232746642307274679399688786114400132341362095006930] elif degree == 11: z = [-0.66126606890073470691013126292248166961816286716800880802421, -0.272180349294785885686295280258287768151235259565335176244192, -0.089759599793713309944142676556141542547561966017018544406214, -0.0166696273662346560965858360898150837154727205519335156053610] else: raise ValueError("Invalid spline degree {0}".format(degree)) # compute overall gain z = np.atleast_1d(z) # apply gain to coeffs c *= np.prod((1 - z) * (1 - 1 / z)) # loop over all poles for pole in z: # causal initialization c[0, ...] = initial_causal_coefficient( c, pole, tolerance, boundary_condition) # causal filter zinit = pole * c[0, ...] zinit = zinit[np.newaxis, ...] if c.ndim < 2: c[1:, ...], _ = signal.lfilter( [1], [1, -pole], c[1:, ...], axis=0, zi=zinit) else: split_size = c.shape[-1] def lfilt(start, width): c[1:, ..., start:start+width], _ = signal.lfilter( [1], [1, -pole], c[1:, ..., start:start+width], axis=0, zi=zinit[:, ..., start:start+width]) parallel.parallelize(lfilt, split_size) # anticausal initialization c[-1, ...] = initial_anticausal_coefficient( c, pole, boundary_condition=boundary_condition) # anticausal filter zinit = pole * c[-1, ...] zinit = zinit[np.newaxis, ...] if c.ndim < 2: c[:-1], _ = signal.lfilter([-pole], [1, -pole], np.flipud(c[0:-1, ...]), axis=0, zi=zinit) else: split_size = c.shape[-1] fc = np.flipud(c[0:-1, ...]) def lfilt2(start, width): c[:-1, ..., start:start+width], _ = signal.lfilter([-pole], [1, -pole], fc[:, ..., start:start+width], axis=0, zi=zinit[:, ..., start:start+width]) parallel.parallelize(lfilt2, split_size) c[:-1] = np.flipud(c[:-1]) return c