Exemple #1
0
def uwt_pysap(img, lvl, Filter='Bspline', n_omp_threads=None):
    import pysap

    lvl -= 1  # TODO !!!!!

    def pysap2muscadet(a_list):
        return np.asarray(a_list)

    nb_scale = lvl + 1  # + 1 for the coarsest scale

    if Filter == 'Bspline':  # = 1st starlet (2nd gen not yet implemented in PySAP)

        transform_name = 'BsplineWaveletTransformATrousAlgorithm'

        transf_kwargs = {}
        if n_omp_threads is not None:
            transf_kwargs['nb_procs'] = n_omp_threads

        # note that if 'n_omp_threads' is not provided,
        # PySAP will automatically set it the
        # max number of CPUs available minus 1

        transform_obj = pysap.load_transform(transform_name)
        transform = transform_obj(nb_scale=nb_scale,
                                  verbose=False,
                                  **transf_kwargs)

    else:
        raise NotImplementedError("Only sarlet transform is supported for now")

    # set the image
    transform.data = img
    transform.analysis()
    coeffs = transform.analysis_data
    return pysap2muscadet(coeffs), transform
def uwt_pysap(img, lvl, Filter='Bspline', n_omp_threads=0):
    """private function : Wavelet transform through PySAP"""

    import pysap
    
    lvl -= 1  # TODO : should be cleaned

    def pysap2muscadet(a_list):
        return np.asarray(a_list)

    nb_scale = lvl+1  # + 1 for the coarsest scale

    if Filter == 'Bspline':  # = 1st starlet (2nd gen not yet implemented in PySAP)

        transform_name = 'BsplineWaveletTransformATrousAlgorithm'

        # note that if 'n_omp_threads' is not provided, 
        # PySAP will automatically set it the 
        # max number of CPUs available minus 1

        transform_obj = pysap.load_transform(transform_name)
        transform = transform_obj(nb_scale=nb_scale, verbose=1, 
                                  padding_mode='symmetric',
                                  nb_procs=n_omp_threads)

    else:
        raise NotImplementedError("Only sarlet transform is supported for now")

    # set the image
    transform.data = img
    transform.analysis()
    coeffs = transform.analysis_data
    return pysap2muscadet(coeffs), transform
Exemple #3
0
    def __init__(self, wavelet_name, nb_scale=4, verbose=0, dim=2,
                 n_coils=1, n_jobs=1, backend="threading", **kwargs):
        """ Initialize the 'WaveletN' class.

        Parameters
        ----------
        wavelet_name: str
            the wavelet name to be used during the decomposition.
        nb_scales: int, default 4
            the number of scales in the decomposition.
        n_coils: int, default 1
            the number of coils for multichannel reconstruction
        n_jobs: int, default 1
            the number of cores to use for multichannel.
        backend: str, default "threading"
            the backend to use for parallel multichannel linear operation.
        verbose: int, default 0
            the verbosity level.
        """
        self.nb_scale = nb_scale
        self.flatten = flatten
        self.unflatten = unflatten
        self.n_jobs = n_jobs
        self.n_coils = n_coils
        self.backend = backend
        self.verbose = verbose
        if wavelet_name not in pysap.AVAILABLE_TRANSFORMS:
            raise ValueError(
                "Unknown transformation '{0}'.".format(wavelet_name))
        transform_klass = pysap.load_transform(wavelet_name)
        self.transform = transform_klass(
            nb_scale=self.nb_scale, verbose=verbose, dim=dim, **kwargs)
        self.coeffs_shape = None
Exemple #4
0
def get_mr_filters(data_shape, opt, n_scales=3, coarse=False, trim=False):
    r"""Get transform filters.

    This method obtains wavelet filters.

    Parameters
    ----------
    data_shape : tuple
        2D data shape
    opt : str
        Name of wavelet transform (in Pysap convention, see Notes)
    n_scales : int, optional
        Number of transform scales.
        Default is ``4``.
    coarse : bool, optional
        Option to keep coarse scale.
        Default is ``False``.
    trim: bool, optional
        Option to trim the filters down to their minimal size
        Default is ``False``.

    Returns
    -------
    numpy.ndarray 3D array of wavelet filters.

    Notes
    -----
    Function copied from Pysap package's astro plugin.
    Added the trim_filter() functionality from the ModOpt package.
    The name of the wavelet transform must be in Pysap convention that
    differs from the sparse2d input arguments.
    To see the available transforms in Pysap, you need to import the
    python module (``import pysap``) and then call
    ``pysap.AVAILABLE_TRANSFORMS``.

    """
    # Adjust the shape of the input data.
    data_shape = np.array(data_shape)
    data_shape += data_shape % 2 - 1

    # Create fake data.
    fake_data = np.zeros(data_shape)
    fake_data[tuple(zip(data_shape // 2))] = 1

    # Transform fake data
    wavelet_transform = (load_transform(opt)(nb_scale=n_scales, verbose=True))
    wavelet_transform.data = fake_data
    wavelet_transform.analysis()
    filters = np.array(wavelet_transform.analysis_data)

    # Added function to replicate ModOpt's get_mr_transform()
    if trim:
        filters = np.array([trim_filter(f) for f in filters])

    # Return filters
    if coarse:
        return filters
    else:
        return filters[:-1]
Exemple #5
0
    def __init__(self,
                 wavelet_name,
                 nb_scale=4,
                 verbose=0,
                 dim=2,
                 n_coils=1,
                 n_jobs=1,
                 backend="threading",
                 **kwargs):
        """ Initialize the 'WaveletN' class.

        Parameters
        ----------
        wavelet_name: str
            the wavelet name to be used during the decomposition.
        nb_scales: int, default 4
            the number of scales in the decomposition.
        n_coils: int, default 1
            the number of coils for multichannel reconstruction
        n_jobs: int, default 1
            the number of cores to use for multichannel.
        backend: str, default "threading"
            the backend to use for parallel multichannel linear operation.
        verbose: int, default 0
            the verbosity level.
        """
        self.nb_scale = nb_scale
        self.flatten = flatten
        self.unflatten = unflatten
        self.n_jobs = n_jobs
        self.n_coils = n_coils
        if self.n_coils == 1 and self.n_jobs != 1:
            print("Making n_jobs = 1 for WaveletN as n_coils = 1")
            self.n_jobs = 1
        self.backend = backend
        self.verbose = verbose
        if wavelet_name not in pysap.AVAILABLE_TRANSFORMS:
            raise ValueError(
                "Unknown transformation '{0}'.".format(wavelet_name))
        transform_klass = pysap.load_transform(wavelet_name)
        self.transform_queue = []
        n_proc = self.n_jobs
        if n_proc < 0:
            n_proc = joblib.cpu_count() + self.n_jobs + 1
        if n_proc > 0:
            if wavelet_name in wavelist()['isap-2d'] or \
                    wavelet_name in wavelist()['isap-3d']:
                warnings.warn("n_jobs is currently unsupported "
                              "for ISAP wavelets, setting n_jobs=1")
                self.n_jobs = 1
                n_proc = 1
        # Create transform queue for parallel execution
        for i in range(min(n_proc, self.n_coils)):
            self.transform_queue.append(
                transform_klass(nb_scale=self.nb_scale,
                                verbose=verbose,
                                dim=dim,
                                **kwargs))
        self.coeffs_shape = None
Exemple #6
0
 def setUp(self):
     """ Get the data from the server.
     """
     self.images = [
         # get_sample_data(dataset_name="astro-fits"),
         get_sample_data(dataset_name="mri-slice-nifti")
     ]
     print("[info] Image loaded for test: {0}.".format(
         [i.data.shape for i in self.images]))
     self.transforms = [
         pysap.load_transform(name) for name in pysap.AVAILABLE_TRANSFORMS
     ]
     print("[info] Found {0} transformations.".format(len(self.transforms)))
     self.nb_scales = [3]  # [2, 3, 4]
     self.nb_iter = 10
Exemple #7
0
 def test_speed(self):
     """ Test the bindings time advantages.
     """
     # With/without bindings
     for strategy, name in ((True, "Without"), (False, "With")):
         tic = time.time()
         transform = pysap.load_transform(
             "LinearWaveletTransformATrousAlgorithm")
         transform = transform(nb_scale=4, verbose=0)
         transform.use_wrapping = strategy
         transform.data = self.images[0]
         for i in range(self.nb_iter):
             transform.analysis()
             recim = transform.synthesis()
         toc = time.time()
         print("[result] {0} bindings execution time: {1}.".format(
             name, toc - tic))
Exemple #8
0
 def setUp(self):
     """ Get the data from the server.
     """
     self.images = [
         # get_sample_data(dataset_name="astro-fits"),
         get_sample_data(dataset_name="mri-slice-nifti")
     ]
     print("[info] Image loaded for test: {0}.".format(
         [i.data.shape for i in self.images]))
     transforms_struct = pysap.wavelist(["isap-2d", "isap-3d"])
     transforms_names = (transforms_struct["isap-2d"] +
                         transforms_struct["isap-3d"])
     self.transforms = [
         pysap.load_transform(name) for name in transforms_names
     ]
     print("[info] Found {0} transformations.".format(len(self.transforms)))
     self.nb_scales = [3]  # [2, 3, 4]
     self.nb_iter = 10
Exemple #9
0
    def test_accessors(self):
        """ Test all the accessors.
        """
        # With/without bindings
        for strategy, name in ((True, "without"), (False, "with")):

            # Test 3-bands undecimated transform
            nb_scale = 4
            print("[info] Test {0} bindings.".format(name))
            transform = pysap.load_transform(
                "NonOrthogonalUndecimatedTransform")
            transform = transform(nb_scale=nb_scale, verbose=0)
            transform.use_wrapping = strategy
            transform.data = self.images[0]
            transform.analysis()

            # Get with scale index only
            for scale in range(nb_scale - 1):
                band_data = transform[scale]
                self.assertEqual(len(band_data), 3)
                for band_array in band_data:
                    self.assertEqual(band_array.shape, (512, 512))
            band_array = transform[nb_scale - 1]
            self.assertEqual(band_array.shape, (512, 512))

            # Get with scale and band
            self.assertEqual(transform[0, 0].shape, (512, 512))

            # Get with scale and band as slice
            band_data = transform[2, 1:3:1]
            self.assertEqual(len(band_data), 2)
            for band_array in band_data:
                self.assertEqual(band_array.shape, (512, 512))

            # Get with scale as slice and band
            band_data = transform[1:3, 0]
            self.assertEqual(len(band_data), 2)
            for band_array in band_data:
                self.assertEqual(band_array.shape, (512, 512))

            # Modify a band on the fly
            band_array = transform[0, 0]
            band_array[:, :] = 10
            self.assertTrue(numpy.allclose(transform[0, 0], band_array))
Exemple #10
0
def get_cospy_filters(data_shape, transform_name, n_scales=4, coarse=False):
    """Get cospy transform filters

    This method obtains wavelet filters by calling cospy

    Parameters
    ----------
    data_shape : tuple
        2D data shape
    transform_name : str
        Name of wavelet transform
    n_scales : int, optional
        Number of transform scales (default is 4)
    coarse : bool, optional
        Option to keep coarse scale (default is 'False')

    Returns
    -------
    np.ndarray 3D array of wavelet filters

    """

    # Adjust the shape of the input data.
    data_shape = np.array(data_shape)
    data_shape += data_shape % 2 - 1

    # Create fake data.
    fake_data = np.zeros(data_shape)
    fake_data[list(zip(data_shape // 2))] = 1

    # Transform fake data
    wavelet_transform = (load_transform(transform_name)(nb_scale=n_scales,
                                                        verbose=True))
    wavelet_transform.data = fake_data
    wavelet_transform.analysis()
    filters = np.array(wavelet_transform.analysis_data)

    # Return filters
    if coarse:
        return filters
    else:
        return filters[:-1]
Exemple #11
0
 def __init__(self,
              wavelet_name,
              nb_scale=4,
              verbose=0,
              dim=2,
              n_coils=1,
              n_jobs=1,
              backend="threading",
              **kwargs):
     self.nb_scale = nb_scale
     self.flatten = flatten
     self.unflatten = unflatten
     self.n_jobs = n_jobs
     self.n_coils = n_coils
     if self.n_coils == 1 and self.n_jobs != 1:
         print("Making n_jobs = 1 for WaveletN as n_coils = 1")
         self.n_jobs = 1
     self.backend = backend
     self.verbose = verbose
     if wavelet_name not in pysap.AVAILABLE_TRANSFORMS:
         raise ValueError(f"Unknown transformation '{wavelet_name}'.")
     transform_klass = pysap.load_transform(wavelet_name)
     self.transform_queue = []
     n_proc = self.n_jobs
     if n_proc < 0:
         n_proc = joblib.cpu_count() + self.n_jobs + 1
     if n_proc > 0:
         if wavelet_name in wavelist()['isap-2d'] or \
                 wavelet_name in wavelist()['isap-3d']:
             warnings.warn("n_jobs is currently unsupported "
                           "for ISAP wavelets, setting n_jobs=1")
             self.n_jobs = 1
             n_proc = 1
     # Create transform queue for parallel execution
     for _ in range(min(n_proc, self.n_coils)):
         self.transform_queue.append(
             transform_klass(nb_scale=self.nb_scale,
                             verbose=verbose,
                             dim=dim,
                             **kwargs))
     self.coeffs_shape = None
Exemple #12
0
    def __init__(self, wavelet_name, nb_scale=4, verbose=0, **kwargs):
        """ Initialize the 'Wavelet2' class.

        Parameters
        ----------
        wavelet_name: str
            the wavelet name to be used during the decomposition.
        nb_scales: int, default 4
            the number of scales in the decomposition.
        verbose: int, default 0
            the verbosity level.
        """
        self.nb_scale = nb_scale
        self.flatten = flatten
        self.unflatten = unflatten
        if wavelet_name not in pysap.AVAILABLE_TRANSFORMS:
            raise ValueError(
                "Unknown transformation '{0}'.".format(wavelet_name))
        transform_klass = pysap.load_transform(wavelet_name)
        self.transform = transform_klass(
            nb_scale=self.nb_scale, verbose=verbose, **kwargs)
        self.coeffs_shape = None
def decompose(data, n_scales=4):
    """ Decompose

    Obtain the wavelet decomposition of the input date using an isotropic
    undecimated wavelet transform.

    Parameters
    ----------
    data : np.ndarray
        Input 2D-array
    n_scales : int, optional
        Number of wavelet scales, default is 4

    Returns
    -------
    np.ndarray
        Wavelet decomposition 3D-array

    Raises
    ------
    TypeError
        For invalid input data type
    TypeError
        For invalid input n_scales type

    Examples
    --------
    >>> import numpy as np
    >>> from tutorial_utils import decompose
    >>> np.random.seed(0)
    >>> data = np.random.ranf((3, 3))
    >>> decompose(data)
    array([[[-0.06020004,  0.09427285, -0.03005594],
            [-0.06932276, -0.21794325, -0.02309608],
            [-0.22873539,  0.17666274,  0.19976479]],

           [[-0.04426706, -0.02943552, -0.01460403],
            [-0.0475564 , -0.01650959,  0.01453722],
            [-0.0240097 ,  0.02943558,  0.08288085]],

           [[-0.0094105 , -0.0110383 , -0.01266617],
            [-0.00393927, -0.00619102, -0.00844282],
            [ 0.01415205,  0.0110383 ,  0.00792474]],

           [[ 0.66269112,  0.6613903 ,  0.66008949],
            [ 0.66570163,  0.66429865,  0.6628958 ],
            [ 0.67618024,  0.67463636,  0.67309237]]])

    """

    if not isinstance(data, np.ndarray) or data.ndim != 2:
        raise TypeError('Input data must be a 2D numpy array.')

    if not isinstance(n_scales, int) or n_scales < 1:
        raise TypeError('n_scales must be a positive integer.')

    if import_pysap:

        trans_name = 'BsplineWaveletTransformATrousAlgorithm'
        trans = load_transform(trans_name)(nb_scale=n_scales,
                                           padding_mode="symmetric")
        trans.data = data
        trans.analysis()

        res = np.array(trans.analysis_data, dtype=np.float)

    else:

        filters = np.load('data/filters_{}.npy'.format(n_scales))
        res = np.array([convolve(data, f) for f in filters])

    return res
Exemple #14
0
from pprint import pprint
import pysap

pprint(pysap.wavelist())
pprint(pysap.wavelist(family="isap-3d"))

#############################################################################
# We illustrate the the decompose/recompose using a 'Daubechies' from pywt
# and 4 scales:

import pysap
from pysap.data import get_sample_data

image = get_sample_data("mri-slice-nifti")
transform_klass = pysap.load_transform("Db3")
transform = transform_klass(nb_scale=4, verbose=1)
transform.data = image
transform.analysis()
transform.show()
rec_image = transform.synthesis()
rec_image.show()

#############################################################################
# We illustrate the the decompose/recompose using a 'FastCurveletTransform'
# from ISAP and 4 scales:

image = get_sample_data("mri-slice-nifti")
transform_klass = pysap.load_transform("FastCurveletTransform")
transform = transform_klass(nb_scale=4, verbose=1)
transform.data = image
Exemple #15
0
def decompose(data, n_scales=4):
    """Decompose.

    Obtain the wavelet decomposition of the input date using an isotropic
    undecimated wavelet transform.

    Parameters
    ----------
    data : np.ndarray
        Input 2D-array
    n_scales : int, optional
        Number of wavelet scales, default is 4

    Returns
    -------
    np.ndarray
        Wavelet decomposition 3D-array

    Raises
    ------
    TypeError
        For invalid input data type
    TypeError
        For invalid input n_scales type

    Examples
    --------
    >>> import numpy as np
    >>> from pysap.astro.denoising.wavelet import decompose
    >>> data = np.arange(9).reshape((3, 3)) * 0.1
    >>> decompose(data)
    array([[[-1.50000006e-01, -1.12500034e-01, -7.50000030e-02],
            [-3.75000238e-02, -2.98023224e-08,  3.74999642e-02],
            [ 7.49999881e-02,  1.12499952e-01,  1.49999976e-01]],

          [[-1.56250030e-01, -1.17187500e-01, -7.81250298e-02],
            [-3.90625000e-02,  0.00000000e+00,  3.90625000e-02],
            [ 7.81250000e-02,  1.17187500e-01,  1.56250000e-01]],

          [[-5.85937500e-02, -4.39453125e-02, -2.92968750e-02],
            [-1.46484375e-02,  0.00000000e+00,  1.46484375e-02],
            [ 2.92968750e-02,  4.39453125e-02,  5.85937500e-02]],

          [[ 3.64843786e-01,  3.73632848e-01,  3.82421911e-01],
            [ 3.91210973e-01,  4.00000036e-01,  4.08789098e-01],
            [ 4.17578161e-01,  4.26367223e-01,  4.35156286e-01]]])

    """
    if not isinstance(data, np.ndarray) or data.ndim != 2:
        raise TypeError('Input data must be a 2D numpy array.')

    if not isinstance(n_scales, int) or n_scales < 1:
        raise TypeError('n_scales must be a positive integer.')

    trans_name = 'BsplineWaveletTransformATrousAlgorithm'
    trans = load_transform(trans_name)(
        nb_scale=n_scales,
        padding_mode="symmetric",
    )
    trans.data = data
    trans.analysis()

    res = np.array(trans.analysis_data, dtype=np.float)

    return res