def test_Wavelet3D_PyWt(self): """Test the adjoint operator for the 3D Wavelet transform """ for ch in self.num_channels: print("Testing with Num Channels : " + str(ch)) for i in range(self.max_iter): print("Process Wavelet3D PyWt test '{0}'...", i) wavelet_op_adj = WaveletN( wavelet_name="sym8", nb_scale=4, dim=3, padding_mode='periodization', n_coils=ch, n_jobs=-1, ) Img = np.squeeze( np.random.randn(ch, self.N, self.N, self.N) + 1j * np.random.randn(ch, self.N, self.N, self.N) ) f_p = wavelet_op_adj.op(Img) f = (np.random.randn(*f_p.shape) + 1j * np.random.randn(*f_p.shape)) I_p = wavelet_op_adj.adj_op(f) x_d = np.vdot(Img, I_p) x_ad = np.vdot(f_p, f) np.testing.assert_allclose(x_d, x_ad, rtol=1e-5) print(" Wavelet3 adjoint test passes")
def test_weighted_sparse_threshold_weights(self): # Test the weighted sparse threshold operator num_scales = 3 linear_op = WaveletN('sym8', nb_scales=num_scales) coeff = linear_op.op(np.zeros((128, 128))) coeffs_shape = linear_op.coeffs_shape scales_shape = np.unique(coeffs_shape, axis=0) constant_weights = WeightedSparseThreshold( weights=1e-10, coeffs_shape=coeffs_shape, ) out = constant_weights.op(np.random.random(coeff.shape)) assert np.all(constant_weights.weights[:np.prod(coeffs_shape[0])] == 0) assert np.all( constant_weights.weights[np.prod(coeffs_shape[0]):] == 1e-10 ) # Scale weights custom_scale_weights = np.arange(num_scales + 1) scale_based = WeightedSparseThreshold( weights=custom_scale_weights, coeffs_shape=coeffs_shape, weight_type='scale_based', zero_weight_coarse=False, ) out = scale_based.op(np.random.random(coeff.shape)) start = 0 for i, scale_shape in enumerate(scales_shape): scale_sz = np.prod(scale_shape) stop = start + scale_sz * np.sum(scale_shape == coeffs_shape) np.testing.assert_equal( scale_based.weights[start:stop], custom_scale_weights[i], ) start = stop # Custom Weights custom_weights = np.random.random(coeff.shape) custom = WeightedSparseThreshold( weights=custom_weights, coeffs_shape=coeffs_shape, weight_type='custom', ) out = custom.op(np.random.random(coeff.shape)) assert np.all(custom.weights[:np.prod(coeffs_shape[0])] == 0) np.testing.assert_equal( custom.weights[np.prod(coeffs_shape[0]):], custom_weights[np.prod(coeffs_shape[0]):], )
def test_Wavelet2D_PyWt(self): """Test the adjoint operator for the 2D Wavelet transform """ for i in range(self.max_iter): print("Process Wavelet2D PyWt test '{0}'...", i) wavelet_op_adj = WaveletN(wavelet_name="sym8", nb_scale=4) Img = (np.random.randn(self.N, self.N) + 1j * np.random.randn(self.N, self.N)) f_p = wavelet_op_adj.op(Img) f = (np.random.randn(*f_p.shape) + 1j * np.random.randn(*f_p.shape)) I_p = wavelet_op_adj.adj_op(f) x_d = np.vdot(Img, I_p) x_ad = np.vdot(f_p, f) np.testing.assert_allclose(x_d, x_ad, rtol=1e-6) print(" Wavelet2 adjoint test passes")
def test_Wavelet2D_ISAP(self): """Test the adjoint operator for the 2D Wavelet transform """ for ch in self.num_channels: print("Testing with Num Channels : " + str(ch)) for i in range(self.max_iter): print("Process Wavelet2D_ISAP test '{0}'...", i) wavelet_op_adj = WaveletN(wavelet_name="HaarWaveletTransform", nb_scale=4, n_coils=ch, n_jobs=2) Img = np.squeeze( np.random.randn(ch, self.N, self.N) + 1j * np.random.randn(ch, self.N, self.N)) f_p = wavelet_op_adj.op(Img) f = (np.random.randn(*f_p.shape) + 1j * np.random.randn(*f_p.shape)) I_p = wavelet_op_adj.adj_op(f) x_d = np.vdot(Img, I_p) x_ad = np.vdot(f_p, f) np.testing.assert_allclose(x_d, x_ad, rtol=1e-5) print(" Wavelet2 adjoint test passes")
def pdhg(data, p, **kwargs): # -- # -- MAIN LOWER LEVEL FUNCTION # -- # INPUTS: - data: kspace measurements # - p: p[:-1]=subsampling mask S(p), p[-1]=regularisation parameter alpha(p) # So len(p)=len(data)+1 # - fourier_op: fourier operator from a full mask of same shape as the final image. # - linear_op: linear operator used in regularisation functions # For the moment, only use waveletN. # - param: lower level energy parameters # Must contain parameters keys "epsilon" and "gamma". # mask_type (optional): type of mask used ("cartesian", "radial"). Assume a cartesian mask if not given. # -- # OPTIONAL INPUTS: # - const: algorithm constants if we already know the values we want to use for tau and sigma # If not given, will compute them according to what is said in the article. # - compute_energy: bool, we compute and return energy over iterations if True (default: False) # - ground_truth: matrix representing the true image the data come from (default: None). If not None, we compute the ssim over iterations. # - maxit,tol: We stop the algorithm when the norm of the difference between two steps # is smaller than tol or after maxit iterations (default: 200, 1e-4) # -- # OUTPUTS: - uk: final image # - norms(, energy, ssims): evolution of stopping criterion (and energy if compute_energy is True / ssims if ground_truth not None) fourier_op = kwargs.get("fourier_op", None) linear_op = kwargs.get("linear_op", None) param = kwargs.get("param", None) # Create fourier_op and linear_op if not given for multithreading if fourier_op is None: samples = kwargs.get("samples", []) shape = kwargs.get("shape", ()) if samples is not None: fourier_op = NonCartesianFFT(samples=samples, shape=shape, implementation='cpu') if fourier_op is None: raise ValueError("A fourier operator fourier_op must be given") if linear_op is None: wavelet_name = kwargs.get("wavelet_name", "") wavelet_scale = kwargs.get("wavelet_scale", 1) if wavelet_name != "": linear_op = WaveletN(wavelet_name=wavelet_name, nb_scale=wavelet_scale, padding_mode="periodization") if linear_op is None: raise ValueError("A linear operator linear_op must be given") if param is None: raise ValueError("Lower level parameters must be given") mask_type = kwargs.get("mask_type", "") const = kwargs.get("const", {}) compute_energy = kwargs.get("compute_energy", False) ground_truth = kwargs.get("ground_truth", None) maxit = kwargs.get("maxit", 200) tol = kwargs.get("tol", 1e-6) verbose = kwargs.get("verbose", 1) #Global parameters p, pn1 = p[:-1], p[-1] epsilon = param["epsilon"] gamma = param["gamma"] n_iter = 0 #Algorithm constants const = compute_constants(param, const, p) if verbose >= 0: print("Sigma:", const["sigma"], "\nTau:", const["tau"]) #Initializing uk = fourier_op.adj_op(p * data) vk = np.copy(uk) wk = linear_op.op(uk) uk_bar = np.copy(uk) norm = 2 * tol #For plots if compute_energy: energy = [] if ground_truth is not None: ssims = [] norms = [] #Main loop t1 = time.time() while n_iter < maxit and norm > tol: uk, vk, wk, uk_bar, norm = step(uk, vk, wk, uk_bar, const, p, pn1, data, param, linear_op, fourier_op, mask_type) n_iter += 1 #Saving informations norms.append(norm) if compute_energy: energy.append( energy_wavelet(uk, p, pn1, data, gamma, epsilon, linear_op, fourier_op)) if ground_truth is not None: ssims.append(ssim(uk, ground_truth)) #Printing if n_iter % 10 == 0 and verbose > 0: if compute_energy: print(n_iter, " iterations:\nCost:", energy[-1], "\nNorm:", norm, "\n") else: print(n_iter, " iterations:\nNorm:", norm, "\n") if verbose >= 0: print("Finished in", time.time() - t1, "seconds.") #Return if compute_energy and ground_truth is not None: return uk, norms, energy, ssims elif ground_truth is not None: return uk, norms, ssims elif compute_energy: return uk, norms, energy else: return uk, norms
print('The Base SSIM is : ' + str(base_ssim)) ############################################################################# # FISTA optimization # ------------------ # # We now want to refine the zero order solution using a FISTA optimization. # The cost function is set to Proximity Cost + Gradient Cost # Setup the operators linear_op = WaveletN( wavelet_name='sym8', nb_scale=4, n_coils=cartesian_ref_image.shape[0], ) coeffs = linear_op.op(cartesian_ref_image) regularizer_op = OWL( alpha=1.05e-8, beta=0, mode='band_based', n_coils=cartesian_ref_image.shape[0], bands_shape=linear_op.coeffs_shape, ) # Setup Reconstructor reconstructor = CalibrationlessReconstructor( fourier_op=fourier_op, linear_op=linear_op, regularizer_op=regularizer_op, gradient_formulation='synthesis', verbose=1, )