def test_wavedecn_shapes_and_size(): wav = pywt.Wavelet('db2') for data_shape in [(33, ), (64, 32), (1, 15, 30)]: for axes in [None, 0, -1]: for mode in pywt.Modes.modes: coeffs = pywt.wavedecn(np.ones(data_shape), wav, mode=mode, axes=axes) # verify that the shapes match the coefficient shapes shapes = pywt.wavedecn_shapes(data_shape, wav, mode=mode, axes=axes) assert_equal(coeffs[0].shape, shapes[0]) expected_size = coeffs[0].size for level in range(1, len(coeffs)): for k, v in coeffs[level].items(): expected_size += v.size assert_equal(shapes[level][k], v.shape) # size can be determined from either the shapes or coeffs size = pywt.wavedecn_size(shapes) assert_equal(size, expected_size) size = pywt.wavedecn_size(coeffs) assert_equal(size, expected_size)
def waveletDenoise(data): # data is num_neurons x time_frames wavelet = pywt.Wavelet('db4') # Determine the maximum number of possible levels for image dlen = wavelet.dec_len wavelet_levels = pywt.dwt_max_level(data.shape[1], wavelet) # Skip coarsest wavelet scales (see Notes in docstring). wavelet_levels = max(wavelet_levels - 3, 1) data_denoise = np.zeros(np.shape(data)) shift = 4 for c in np.arange(-shift, shift + 1): data_shift = np.roll(data, c, 1) for i in range(np.shape(data)[0]): coeffs = pywt.wavedecn(data_shift[i, :], wavelet=wavelet, level=wavelet_levels) # Detail coefficients at each decomposition level dcoeffs = coeffs[1:] detail_coeffs = dcoeffs[-1]['d'] # rescaling using a single estimation of level noise based on first level coefficients. # Consider regions with detail coefficients exactly zero to be masked out # detail_coeffs = detail_coeffs[np.nonzero(detail_coeffs)] # 75th quantile of the underlying, symmetric noise distribution denom = scipy.stats.norm.ppf(0.75) sigma = np.median(np.abs(detail_coeffs)) / denom np.shape(sigma) sigma_mat = np.tile(sigma, (wavelet_levels, 1)) np.shape(sigma_mat) tot_num_coeffs = pywt.wavedecn_size(coeffs) # universal threshold threshold = np.sqrt(2 * np.log(tot_num_coeffs)) threshold = sigma * threshold denoised_detail = [{ key: pywt.threshold(level[key], value=threshold, mode='hard') for key in level } for level in dcoeffs] # Dict of unique threshold coefficients for each detail coeff. array denoised_coeffs = [coeffs[0]] + denoised_detail data_denoise[i, :] = data_denoise[i, :] + np.roll( pywt.waverecn(denoised_coeffs, wavelet), -c)[:data_denoise.shape[1]] data_denoise = data_denoise / (2 * shift + 1) return data_denoise
def __init__(self, space, wavelet, nlevels, variant, pad_mode='constant', pad_const=0, impl='pywt', axes=None): """Initialize a new instance. Parameters ---------- space : `DiscreteLp` Domain of the forward wavelet transform (the "image domain"). In the case of ``variant in ('inverse', 'adjoint')``, this space is the range of the operator. wavelet : string or `pywt.Wavelet` Specification of the wavelet to be used in the transform. If a string is given, it is converted to a `pywt.Wavelet`. Use `pywt.wavelist` to get a list of available wavelets. Possible wavelet families are: ``'haar'``: Haar ``'db'``: Daubechies ``'sym'``: Symlets ``'coif'``: Coiflets ``'bior'``: Biorthogonal ``'rbio'``: Reverse biorthogonal ``'dmey'``: Discrete FIR approximation of the Meyer wavelet variant : {'forward', 'inverse', 'adjoint'} Wavelet transform variant to be created. nlevels : positive int, optional Number of scaling levels to be used in the decomposition. The maximum number of levels can be calculated with `pywt.dwtn_max_level`. Default: Use maximum number of levels. pad_mode : string, optional Method to be used to extend the signal. ``'constant'``: Fill with ``pad_const``. ``'symmetric'``: Reflect at the boundaries, not repeating the outmost values. ``'periodic'``: Fill in values from the other side, keeping the order. ``'order0'``: Extend constantly with the outmost values (ensures continuity). ``'order1'``: Extend with constant slope (ensures continuity of the first derivative). This requires at least 2 values along each axis where padding is applied. ``'pywt_per'``: like ``'periodic'``-padding but gives the smallest possible number of decomposition coefficients. Only available with ``impl='pywt'``, See ``pywt.Modes.modes``. ``'reflect'``: Reflect at the boundary, without repeating the outmost values. ``'antisymmetric'``: Anti-symmetric variant of ``symmetric``. ``'antireflect'``: Anti-symmetric variant of ``reflect``. For reference, the following table compares the naming conventions for the modes in ODL vs. PyWavelets:: ======================= ================== ODL PyWavelets ======================= ================== symmetric symmetric reflect reflect order1 smooth order0 constant constant, pad_const=0 zero periodic periodic pywt_per periodization antisymmetric antisymmetric antireflect antireflect ======================= ================== See `signal extension modes`_ for an illustration of the modes (under the PyWavelets naming conventions). pad_const : float, optional Constant value to use if ``pad_mode == 'constant'``. Ignored otherwise. Constants other than 0 are not supported by the ``pywt`` back-end. impl : {'pywt'}, optional Back-end for the wavelet transform. axes : sequence of ints, optional Axes over which the DWT that created ``coeffs`` was performed. The default value of ``None`` corresponds to all axes. When not all axes are included this is analagous to a batch transform in ``len(axes)`` dimensions looped over the non-transformed axes. In orther words, filtering and decimation does not occur along any axes not in ``axes``. References ---------- .. _signal extension modes: https://pywavelets.readthedocs.io/en/latest/ref/signal-extension-modes.html """ if not isinstance(space, DiscreteLp): raise TypeError('`space` {!r} is not a `DiscreteLp` instance.' ''.format(space)) self.__impl, impl_in = str(impl).lower(), impl if self.impl not in _SUPPORTED_WAVELET_IMPLS: raise ValueError("`impl` '{}' not supported".format(impl_in)) if axes is None: axes = tuple(range(space.ndim)) elif np.isscalar(axes): axes = (axes, ) elif len(axes) > space.ndim: raise ValueError("Too many axes.") self.axes = tuple(axes) if nlevels is None: nlevels = pywt.dwtn_max_level(space.shape, wavelet, self.axes) self.__nlevels, nlevels_in = int(nlevels), nlevels if self.nlevels != nlevels_in: raise ValueError('`nlevels` must be integer, got {}' ''.format(nlevels_in)) self.__impl, impl_in = str(impl).lower(), impl if self.impl not in _SUPPORTED_WAVELET_IMPLS: raise ValueError("`impl` '{}' not supported".format(impl_in)) self.__wavelet = getattr(wavelet, 'name', str(wavelet).lower()) self.__pad_mode = str(pad_mode).lower() self.__pad_const = space.field.element(pad_const) if self.impl == 'pywt': self.pywt_pad_mode = pywt_pad_mode(pad_mode, pad_const) self.pywt_wavelet = pywt_wavelet(self.wavelet) # determine coefficient shapes (without running wavedecn) self._coeff_shapes = pywt.wavedecn_shapes(space.shape, wavelet, mode=self.pywt_pad_mode, level=self.nlevels, axes=self.axes) # precompute slices into the (raveled) coeffs self._coeff_slices = precompute_raveled_slices(self._coeff_shapes) coeff_size = pywt.wavedecn_size(self._coeff_shapes) coeff_space = space.tspace_type(coeff_size, dtype=space.dtype) else: raise RuntimeError("bad `impl` '{}'".format(self.impl)) variant, variant_in = str(variant).lower(), variant if variant not in ('forward', 'inverse', 'adjoint'): raise ValueError("`variant` '{}' not understood" "".format(variant_in)) self.__variant = variant if variant == 'forward': super(WaveletTransformBase, self).__init__(domain=space, range=coeff_space, linear=True) else: super(WaveletTransformBase, self).__init__(domain=coeff_space, range=space, linear=True)
+-------------------------------+-------------------------------+ """ cam = pywt.data.camera() coeffs = pywt.wavedecn(cam, wavelet="db2", level=3) # Concatenating all coefficients into a single n-d array arr, coeff_slices = pywt.coeffs_to_array(coeffs) # Splitting concatenated coefficient array back into its components coeffs_from_arr = pywt.array_to_coeffs(arr, coeff_slices) cam_recon = pywt.waverecn(coeffs_from_arr, wavelet='db2') # Raveling coefficients to a 1D array arr, coeff_slices, coeff_shapes = pywt.ravel_coeffs(coeffs) # Unraveling coefficients from a 1D array coeffs_from_arr = pywt.unravel_coeffs(arr, coeff_slices, coeff_shapes) cam_recon2 = pywt.waverecn(coeffs_from_arr, wavelet='db2') # Multilevel: n-d coefficient shapes shapes = pywt.wavedecn_shapes((64, 32), 'db2', mode='periodization') # Multilevel: Total size of all coefficients size = pywt.wavedecn_size(shapes) print(size) print()