def histogram(image, nbins=256, lower_cut=0., cumulate=0): """ Compute the histogram of an input dataset. Parameters ---------- image: Image the image that contains the dataset to be analysed. nbins: int, default 256 the histogram number of bins. lower_cut: float, default 0 do not consider the intensities under this threshold. cumulate: bool, default False if set compute the cumulate histogram. Returns ------- hist_im: Image the generated histogram. """ hist, bins = np.histogram(image.data[image.data > lower_cut], nbins) if cumulate: cdf = hist.cumsum() cdf_normalized = cdf * hist.max() / cdf.max() hist_im = pysap.Image(data=cdf_normalized) else: hist_im = pysap.Image(data=hist) return hist_im
def _synthesis(self, analysis_data, analysis_header): """ Reconstruct a real signal from the wavelet coefficients using ISAP. Parameters ---------- analysis_data: list of nd-array the wavelet coefficients array. analysis_header: dict the wavelet decomposition parameters. Returns ------- data: nd-array the reconstructed data array. """ # Use subprocess to execute binaries if self.use_wrapping: cube = pysap.Image(data=analysis_data[0], metadata=analysis_header) with pysap.TempDir(isap=True) as tmpdir: in_mr_file = os.path.join(tmpdir, "cube.mr") out_image = os.path.join(tmpdir, "out.fits") pysap.io.save(cube, in_mr_file) pysap.extensions.mr_recons(in_mr_file, out_image, verbose=(self.verbose > 0)) data = pysap.io.load(out_image).data # Use Python bindings else: data = self.trf.reconstruct(analysis_data) return data
def _op(self, data): if isinstance(data, np.ndarray): data = pysap.Image(data=data) self.transform.data = data self.transform.analysis() coeffs, coeffs_shape = flatten(self.transform.analysis_data) return coeffs, coeffs_shape
def filter(self, data): """ Execute the filter operation. Parameters ---------- data: ndarray the input data. """ self.data = pysap.Image(data=self.flt.filter(data))
def _op(self, data): if isinstance(data, np.ndarray): data = pysap.Image(data=data) # Get the transform from queue transform = self.transform_queue.pop() transform.data = data transform.analysis() coeffs, coeffs_shape = flatten(transform.analysis_data) # Add back the transform to the queue self.transform_queue.append(transform) return coeffs, coeffs_shape
def deconvolve(self, img, psf): """ Execute the deconvolution operation. Parameters ---------- img: ndarray the input image. psf: ndarray the input psf """ self.data = pysap.Image(data=self.deconv.deconvolve(img, psf))
def synthesis(self): """ Reconstruct a real or complex signal from the wavelet coefficients using ISAP. Returns ------- data: pysap.Image the reconstructed data/signal. """ # Checks if self._analysis_data is None: raise ValueError("Please specify first the decomposition " "coefficients array.") if self.use_wrapping and self._analysis_header is None: raise ValueError("Please specify first the decomposition " "coefficients header.") # Message if self.verbose > 1: print("[info] Synthesis header:") pprint(self._analysis_header) # Reorganize the coefficents with ISAP convention # TODO: do not backup the list of bands if self.use_wrapping: analysis_buffer = numpy.zeros( self._analysis_buffer_shape, dtype=self.analysis_data[0].dtype) for scale, nb_bands in enumerate(self.nb_band_per_scale): for band in range(nb_bands): self._set_linear_band(scale, band, analysis_buffer, self.band_at(scale, band)) _saved_analysis_data = self._analysis_data self._analysis_data = analysis_buffer self._analysis_data = [self.unflatten_fct(self)] # Synthesis if numpy.iscomplexobj(self._analysis_data[0]): data_real = self._synthesis( [arr.real for arr in self._analysis_data], self._analysis_header) data_imag = self._synthesis( [arr.imag for arr in self._analysis_data], self._analysis_header) data = data_real + 1.j * data_imag else: data = self._synthesis( self._analysis_data, self._analysis_header) # TODO: remove this code asap if self.use_wrapping: self._analysis_data = _saved_analysis_data return pysap.Image(data=data, metadata=self._image_metadata)
def save(image, path): """ Save an image. Parameters ---------- image: Image or ndarray the data to be saved. path: str the destination file. """ # Get the data if not isinstance(image, pysap.Image): image = pysap.Image(data=image) # Save the data saver = get_saver(path) saver.save(image, path)
def op(self, data): """ Define the wavelet operator. This method returns the input data convolved with the wavelet filter. Parameters ---------- data: ndarray or Image input 2D data array. Returns ------- coeffs: ndarray the wavelet coefficients. """ if isinstance(data, numpy.ndarray): data = pysap.Image(data=data) self.transform.data = data self.transform.analysis() coeffs, self.coeffs_shape = flatten(self.transform.analysis_data) return coeffs
def scaling(image, method="stretching"): """ Change the image dynamic. Parameters ---------- image: Image the image to be transformed. method: str, default 'stretching' the normalization method: 'stretching', 'equalization' or 'adaptive'. Returns ------- normalize_image: Image the normalized image. """ # Contrast stretching if method == "stretching": p2, p98 = np.percentile(image.data, (2, 98)) norm_data = exposure.rescale_intensity(image.data, in_range=(p2, p98)) # Equalization elif method == "equalization": norm_data = exposure.equalize_hist(image.data) # Adaptive Equalization elif method == "adaptive": norm_data = exposure.equalize_adapthist(image.data, clip_limit=0.03) # Unknown method else: raise ValueError("Unknown normalization '{0}'.".format(method)) normalize_image = pysap.Image(data=norm_data) return normalize_image
############################################################################# # Generate the kspace # ------------------- # # From the 3D Orange volume and the acquisition mask, we retrospectively # undersample the k-space using a cartesian acquisition mask # We then reconstruct the zero order solution as a baseline # Get the locations of the kspace samples kspace_loc = convert_mask_to_locations(mask.data) # Generate the subsampled kspace fourier_op = FFT(samples=kspace_loc, shape=image.shape) kspace_data = fourier_op.op(image) # Zero order solution image_rec0 = pysap.Image(data=fourier_op.adj_op(kspace_data), metadata=image.metadata) # image_rec0.show() # Calculate SSIM base_ssim = ssim(image_rec0, image) print(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(
from pysap.numerics.utils import convert_mask_to_locations from pysap.numerics.utils import convert_locations_to_mask from pysap.numerics.gradient import Gradient_pMRI from pysap.numerics.proximity import Threshold # Third party import import numpy as np import scipy.fftpack as pfft # Loading input data Il = get_sample_data("2d-pmri").data.astype("complex128") SOS = np.squeeze(np.sqrt(np.sum(np.abs(Il)**2, axis=0))) Smaps = np.asarray([Il[channel] / SOS for channel in range(Il.shape[0])]) samples = get_sample_data("mri-radial-samples").data mask = pfft.fftshift(convert_locations_to_mask(samples, SOS.shape)) image = pysap.Image(data=np.abs(SOS)) image.show() ############################################################################# # Generate the kspace # ------------------- # # From the 2D brain slice and the acquistion mask, we generate the acquisition # measurments, the observed kspace. # We then reconstruct the zero order solution. # Generate the subsampled kspace Sl = np.asarray([Smaps[l] * SOS for l in range(Smaps.shape[0])]) kspace_data = np.asarray([mask * pfft.fft2(Sl[l]) for l in range(Sl.shape[0])]) mask = pysap.Image(data=pfft.fftshift(mask)) mask.show()
# Package import from mri.operators import FFT, WaveletN from mri.operators.utils import convert_mask_to_locations from mri.reconstructors import SelfCalibrationReconstructor import pysap from pysap.data import get_sample_data # Third party import from modopt.math.metrics import ssim from modopt.opt.linear import Identity from modopt.opt.proximity import SparseThreshold import numpy as np # Loading input data cartesian_ref_image = get_sample_data('2d-pmri') image = pysap.Image(data=np.sqrt(np.sum(cartesian_ref_image.data**2, axis=0))) # Obtain MRI cartesian mask mask = get_sample_data("cartesian-mri-mask") kspace_loc = convert_mask_to_locations(mask.data) # View Input # image.show() # mask.show() ############################################################################# # Generate the kspace # ------------------- # # From the 2D brain slice and the acquisition mask, we retrospectively # undersample the k-space using a cartesian acquisition mask # We then reconstruct the zero order solution as a baseline
non_cartesian=True, uniform_data_shape=[N, N], gradient_space="analysis") max_iter = 200 # Strating the reconstruction process x_final, transform, costs, metrics = sparse_rec_condatvu( gradient_op, linear_op, prox_op, cost_op, std_est=None, std_est_method=None, std_thr=2., mu=1e-7, tau=None, sigma=None, relaxation_factor=1.0, nb_of_reweights=0, max_nb_of_iter=max_iter, add_positivity=True, atol=1e-4, verbose=1) Image = pysap.Image(data=np.abs(x_final)) Image.show() # In[ ]:
fourier_op = NonCartesianFFT( samples=kspace_loc, shape=image.shape, implementation='gpuNUFFT', ) fourier_op_density_comp = NonCartesianFFT( samples=kspace_loc, shape=image.shape, implementation='gpuNUFFT', density_comp=density_comp ) # Get the kspace data retrospectively. Note that this can be done with # `fourier_op_density_comp` as the forward operator is the same kspace_obs = fourier_op.op(image.data) # Simple adjoint image_rec0 = pysap.Image(data=np.abs(fourier_op.adj_op(kspace_obs))) # image_rec0.show() base_ssim = ssim(image_rec0, image) print('The SSIM from Adjoint is : ' + str(base_ssim)) # Density Compensation adjoint: # This preconditions k-space giving a result closer to inverse image_rec1 = pysap.Image(data=np.abs( fourier_op_density_comp.adj_op(kspace_obs)) ) # image_rec1.show() new_ssim = ssim(image_rec1, image) print('The SSIM from Density ' 'compensated Adjoint is : ' + str(new_ssim))
# Loading testing data image = get_sample_data("mri-slice-nifti") mask = get_sample_data("mri-mask") image.show() mask.show() # Generate the subsampled kspace kspace_mask = pfft.ifftshift(mask.data) kspace_data = pfft.fft2(image.data) * kspace_mask # Get the locations of the kspace samples kspace_loc = convert_mask_to_locations(kspace_mask) # Zero order solution image_rec0 = pysap.Image(data=pfft.ifft2(kspace_data), metadata=image.metadata) image_rec0.show() ############################################################################# # Setting the reconstruction parameters # ------------------------------------- fourier_op = FFT2(kspace_loc, image.data.shape) gradient_op = GradAnalysis2(data=kspace_data, fourier_op=fourier_op) linear_op = DictionaryLearning(img_shape=image.data.shape, dictionary_r=dico_real, dictionary_i=dico_imag) prox_dual_op = Threshold(None) cost_op = DualGapCost(linear_op=linear_op, initial_cost=1e6, tolerance=1e-4,
import pysap from pysap.data import get_sample_data # Third party import from modopt.math.metrics import ssim from modopt.opt.linear import Identity from modopt.opt.proximity import SparseThreshold import numpy as np # Loading input data image = get_sample_data('2d-mri') # Obtain MRI non-cartesian mask radial_mask = get_sample_data("mri-radial-samples") kspace_loc = radial_mask.data mask = pysap.Image(data=convert_locations_to_mask(kspace_loc, image.shape)) # View Input # image.show() # mask.show() ############################################################################# # Generate the kspace # ------------------- # # From the 2D brain slice and the acquisition mask, we retrospectively # undersample the k-space using a radial acquisition mask # We then reconstruct the zero order solution as a baseline # Get the locations of the kspace samples and the associated observations fourier_op = NonCartesianFFT(samples=kspace_loc,
# Generate the kspace # ------------------- # # From the 2D brain slice and the acquistion mask, we generate the acquisition # measurments, the observed kspace. # We then reconstruct the zero order solution. # Generate the subsampled kspace kspace_mask = pfft.ifftshift(mask.data) kspace_data = pfft.fft2(image.data) * kspace_mask # Get the locations of the kspace samples kspace_loc = convert_mask_to_locations(kspace_mask) # Zero order solution image_rec0 = pysap.Image(data=pfft.ifft2(kspace_data), metadata=image.metadata) image_rec0.show() ############################################################################# # FISTA optimization # ------------------ # # We now want to refine the zero order solution using a FISTA optimization. # Here no cost function is set, and the optimization will reach the # maximum number of iterations. Fill free to play with this parameter. # Start the FISTA reconstruction max_iter = 20 x_final, transform = sparse_rec_fista( data=kspace_data, wavelet_name="BsplineWaveletTransformATrousAlgorithm",
# Third party import import numpy as np import scipy.fftpack as pfft from scipy.io import loadmat import matplotlib.pyplot as plt # Loading input data image_name = '/home/loubnaelgueddari/Data'\ '/meas_MID41_CSGRE_ref_OS1_FID14687.mat' k_space_ref = loadmat(image_name)['ref'] k_space_ref /= np.linalg.norm(k_space_ref) Smaps, SOS = get_Smaps(k_space_ref, (512, 512), mode='FFT') mask = get_sample_data("mri-mask") # mask.show() image = pysap.Image(data=np.abs(SOS), metadata=mask.metadata) image.show() ############################################################################# # Generate the kspace # ------------------- # # From the 2D brain slice and the acquistion mask, we generate the acquisition # measurments, the observed kspace. # We then reconstruct the zero order solution. # Generate the subsampled kspace Sl = prod_over_maps(Smaps, SOS) kspace_data = function_over_maps(pfft.fft2, Sl) kspace_data = prod_over_maps(kspace_data, mask.data) mask.show()
from pysap.numerics.gradient import Gradient_pMRI from pysap.numerics.proximity import Threshold from pysap.plugins.mri.parallel_mri.extract_sensitivity_maps import ( extract_k_space_center_and_locations, get_Smaps) from pysap.plugins.mri.reconstruct.utils import normalize_frequency_locations # Third party import import numpy as np # Loading input data Il = get_sample_data("2d-pmri").data.astype("complex128") SOS = np.squeeze(np.sqrt(np.sum(np.abs(Il)**2, axis=0))) Smaps = np.asarray([Il[channel] / SOS for channel in range(Il.shape[0])]) kspace_loc = normalize_frequency_locations( get_sample_data("mri-radial-samples").data) image = pysap.Image(data=np.abs(SOS)) image.show() ############################################################################# # Generate the kspace # ------------------- # # From the 2D brain slice and the acquistion mask, we generate the acquisition # measurments, the observed kspace. # We then reconstruct the zero order solution. # Generate the subsampled kspace fourier_op_gen = NFFT2(samples=kspace_loc, shape=SOS.shape) kspace_data = np.asarray( [fourier_op_gen.op(Il[l]) for l in range(Il.shape[0])])
from mri.reconstructors import SelfCalibrationReconstructor from mri.reconstructors.utils.extract_sensitivity_maps import get_Smaps from mri.operators.utils import convert_locations_to_mask, \ gridded_inverse_fourier_transform_nd import pysap from pysap.data import get_sample_data # Third party import from modopt.math.metrics import ssim from modopt.opt.linear import Identity from modopt.opt.proximity import SparseThreshold import numpy as np # Loading input data cartesian_ref_image = get_sample_data('2d-pmri') image = pysap.Image(data=np.sqrt(np.sum(cartesian_ref_image.data**2, axis=0))) # Obtain MRI cartesian mask mask = get_sample_data("mri-radial-samples") kspace_loc = mask.data # View Input # image.show() # mask.show() ############################################################################# # Generate the kspace # ------------------- # # From the 2D brain slice and the acquisition mask, we retrospectively # undersample the k-space using a non cartesian acquisition mask
from mri.operators.utils import convert_locations_to_mask, \ gridded_inverse_fourier_transform_stack, get_stacks_fourier, \ convert_mask_to_locations from mri.reconstructors import SingleChannelReconstructor import pysap from pysap.data import get_sample_data # Third party import from modopt.math.metrics import ssim from modopt.opt.linear import Identity from modopt.opt.proximity import SparseThreshold import numpy as np # Loading input data image = get_sample_data('3d-pmri') image = pysap.Image(data=np.sqrt(np.sum(np.abs(image.data)**2, axis=0))) # Reducing the size of the volume for faster computation image.data = image.data[:, :, 48:-48] # Obtain MRI non-cartesian sampling plane mask_radial = get_sample_data("mri-radial-samples") # Tiling the plane on the z-direction # sampling_z = np.ones(image.shape[2]) # no sampling sampling_z = np.random.randint(2, size=image.shape[2]) # random sampling sampling_z[22:42] = 1 Nz = sampling_z.sum() # Number of acquired plane z_locations = np.repeat(convert_mask_to_locations(sampling_z), mask_radial.shape[0])