Exemplo n.º 1
0
 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")
Exemplo n.º 2
0
    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]):],
        )
Exemplo n.º 3
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")
Exemplo n.º 4
0
 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")
Exemplo n.º 5
0
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,
)