def plot_filters(bank=None, filt_opt_bank = None):
    if bank is None:
        filt_opt_bank, bank = test_filter_bank(return_bank=True)
        
    for k in range(2):
        print('Bank {}'.format(k))
        center_psi, bw_psi, bw_phi  = morlet_freq_1d(filt_opt_bank[k])  

        sigma0 = bank[k].meta.sigma0
        sigma_psi = sigma0*np.pi/2./bw_psi
        sigma_phi = sigma0*np.pi/2./bw_phi

        J = bank[k].meta.J
        P = bank[k].meta.P
        print('J = {}, P = {}'.format(J, P))

        for j in range(J)[::J//5]:

            f = bank[k].psi.filter[j]
#             f = np.concatenate([f[:len(f)//2][::-1], f[:len(f)//2]])

            ifft_f = mkl_fft.ifft(f)
            ifft_f = np.real(ifft_f)

            fig, ax = plt.subplots(1, 2, figsize = (24, 4))
            ax[0].plot(np.concatenate([ifft_f[-int(3*sigma_psi[-1]):],
                                       ifft_f[:int(3*sigma_psi[-1])]]))
#             ax[0].plot(ifft_f)

            ax[1].plot(f)
#             ax[1].plot(np.concatenate([f[:len(f)//2][::-1], f[:len(f)//2]]))

            fig.suptitle('Psi filter, j{} = {}'.format(k+1, j), size = 'xx-large')
            ax[0].set_title('Time domain')
            ax[1].set_title('Frequency domain')

            plt.show()
            
        
        if P > 0:
            f = bank[k].phi.filter[0]

            ifft_f = mkl_fft.ifft(f)
            ifft_f = np.real(ifft_f)

            fig, ax = plt.subplots(1, 2, figsize = (24, 4))
            ax[0].plot(np.concatenate([ifft_f[-int(3*sigma_psi[-1]):],
                                       ifft_f[:int(3*sigma_psi[-1])]]))
#             ax[0].plot(ifft_f)
            ax[1].plot(f)
            
            fig.suptitle('Phi filter', size = 'xx-large')
            ax[0].set_title('Time domain')
            ax[1].set_title('Frequency domain')
            
            plt.show()
Exemple #2
0
 def FFT_t_2(self, A):
     if MKL_AVAILABLE:
         if global_variables.PRE_FFTSHIFT:
             return mkl_fft.ifft(A)
         else:
             return ifftshift(mkl_fft.ifft(fftshift(A)))
     else:
         if global_variables.PRE_FFTSHIFT:
             return scipy.fftpack.ifft(A)
         else:
             return ifftshift(scipy.fftpack.ifft(fftshift(A)))
Exemple #3
0
def mkl_ifft1d(a):
    
    n,m = a.shape
    b = np.zeros((n,m),dtype=np.complex128)
    for i in xrange(m):
        b[:,i] = mkl_fft.ifft(a[:,i]+0j)/n
    return b
Exemple #4
0
def ifft(a, overwrite_x = False):
    """Computes  ifft on a matrix of shape (..., n).
    
    This is identical to np.ifft2(a)
    
    Parameters
    ----------
    a : array_like
        Input array (must be complex).
    overwrite_x : bool
        Specifies whether original array can be destroyed (for inplace transform)
       
    Returns
    -------
    out : complex ndarray
        Result of the transformation along the (-4,-3) axes.    
    """
    a = np.asarray(a, dtype = CDTYPE)      
    libname = DTMMConfig["fftlib"]    
    if libname == "mkl_fft":
        return mkl_fft.ifft(a, overwrite_x = overwrite_x)
    elif libname == "scipy":
        return spfft.ifft(a,  overwrite_x = overwrite_x)
    elif libname == "numpy":
        return npfft.ifft(a)
    elif libname == "pyfftw":
        return pyfftw.interfaces.scipy_fft.ifft(a, overwrite_x = overwrite_x)
    else: #default implementation is numpy
        return npfft.ifft(a)
def mkl_ifft1d(a):
    
    n,m = a.shape
    b = np.zeros((n,m),dtype=np.complex128)
    for i in xrange(m):
        b[:,i] = mkl_fft.ifft(a[:,i]+0j)/n
    return b
    def test_vector3(self):
        "fft(ifft(x)) is identity"
        f1 = mkl_fft.ifft(self.xz1)
        f2 = mkl_fft.fft(f1)
        assert_(np.allclose(self.xz1,f2))

        f1 = mkl_fft.ifft(self.xc1)
        f2 = mkl_fft.fft(f1)
        assert_( np.allclose(self.xc1,f2))

        f1 = mkl_fft.ifft(self.xd1)
        f2 = mkl_fft.fft(f1)
        assert_( np.allclose(self.xd1,f2))

        f1 = mkl_fft.ifft(self.xf1)
        f2 = mkl_fft.fft(f1)
        assert_( np.allclose(self.xf1, f2, atol = 2.0e-7))
Exemple #7
0
def mifft(fh):
    M = fh.shape[0]
    NS = fh.shape[1]
    N = NS + 1
    N2 = int(N / 2)
    temp = np.empty((M, N), dtype=complex)
    temp[:, :N2] = fh[:, :N2]
    temp[:, N2] = 0.0
    temp[:, N2 + 1:] = fh[:, N2:]
    return ifft(temp)
Exemple #8
0
def _ifft(a, overwrite_x=False):
    libname = CDDMConfig["fftlib"]
    if libname == "mkl_fft":
        return mkl_fft.ifft(a, overwrite_x=overwrite_x)
    elif libname == "scipy":
        return spfft.ifft(a, overwrite_x=overwrite_x)
    elif libname == "pyfftw":
        return fftw.scipy_fftpack.ifft(a, overwrite_x=overwrite_x)
    elif libname == "numpy":
        return np.fft.ifft(a)
Exemple #9
0
    def test_scale_1d_array(self):
        X = np.ones((8, 4, 4,), dtype='d')
        f1 = mkl_fft.fft(X, axis=1, forward_scale=0.25)
        f2 = mkl_fft.fft(X, axis=1)
        r_tol, a_tol = _get_rtol_atol(X)
        assert_allclose(4*f1, f2, rtol=r_tol, atol=a_tol)

        X1 = mkl_fft.ifft(f1, axis=1, forward_scale=0.25)
        assert_allclose(X, X1, rtol=r_tol, atol=a_tol)

        f3 = mkl_fft.rfft(X, axis=0, forward_scale=0.5)
        X2 = mkl_fft.irfft(f3, axis=0, forward_scale=0.5)
        assert_allclose(X, X2, rtol=r_tol, atol=a_tol)
Exemple #10
0
    def test_scale_1d_vector(self):
        X = np.ones(128, dtype='d')
        f1 = mkl_fft.fft(X, forward_scale=0.25)
        f2 = mkl_fft.fft(X)
        r_tol, a_tol = _get_rtol_atol(X)
        assert_allclose(4*f1, f2, rtol=r_tol, atol=a_tol)

        X1 = mkl_fft.ifft(f1, forward_scale=0.25)
        assert_allclose(X, X1, rtol=r_tol, atol=a_tol)

        f3 = mkl_fft.rfft(X, forward_scale=0.5)
        X2 = mkl_fft.irfft(f3, forward_scale=0.5)
        assert_allclose(X, X2, rtol=r_tol, atol=a_tol)
Exemple #11
0
def hilbert(signal: np.ndarray) -> np.ndarray:
    """
    hilbert(signal)

    calculate the analytic signal using the `Hilbert transform` (same with scipy.signal.hilbert)

    .. math::
        S_a = S + iS_H

        where S_H is the hilbert transform of the signal

    Parameters
    ----------
        signal : np.ndarray
            signal

    Returns
    -------
        np.ndarray
           :math:'s + s_{H} i'
    """
    @njit
    def _modifyfft(x: np.ndarray) -> np.ndarray:
        """used by the function hilbert

        Parameters
        ----------
            x : np.ndarray
                [description]

        Returns
        -------
            np.ndarray
                [description]
        """
        N = x.size
        if N % 2 == 0:
            x[1:N // 2] = x[1:N // 2] * 2
            x[N // 2 + 1:] = 0
        else:
            x[1:(N + 1) // 2] = x[1:(N + 1) // 2] * 2
            x[(N + 1) // 2:] = 0
        return x

    Xf = fft(signal)
    Xf = _modifyfft(Xf)
    x = ifft(Xf)
    return x
Exemple #12
0
    def test_fft(self):

        n_tests = 1000
        n_max = 2
        d_max = 100

        norm = 'ortho'
        inplace = True
        scrambled = True

        passed = True

        for i in range(n_tests):
            ndim = np.random.randint(1, high=n_max + 1)
            axis = np.random.randint(0, high=ndim)
            dims = np.random.randint(1, high=d_max + 1, size=(ndim))

            x = np.random.normal(size=dims) + 1j * np.random.normal(size=dims)

            if inplace:
                X = x.copy()
                fft(X, axis=axis, norm=norm, out=X, scrambled=scrambled)
            else:
                X = fft(x, axis=axis, norm=norm, scrambled=scrambled)

            Y = np.fft.fft(x, axis=axis, norm=norm)

            x_ = ifft(X, axis=axis, norm=norm)

            if not np.allclose(X, Y) and not scrambled:
                print(
                    '  Failed forward with ndim=%d axis=%d dims=' %
                    (ndim, axis), dims)
                passed = False

            if not np.allclose(x, x_):
                print(
                    '  Failed backward with ndim=%d axis=%d dims=' %
                    (ndim, axis), dims)
                passed = False

        self.assertTrue(passed)
Exemple #13
0
    def test_fft_truncation(self):

        n_tests = 1000
        n_max = 2
        d_max = 100

        norm = None
        inplace = False
        scrambled = False

        passed = True

        for i in range(n_tests):
            ndim = np.random.randint(1, high=n_max + 1)
            axis = np.random.randint(0, high=ndim)
            dims = np.random.randint(2, high=d_max + 1, size=(ndim))

            x = np.random.normal(size=dims) + 1j * np.random.normal(size=dims)
            x_trunc = np.swapaxes(x, axis, -1)[..., :dims[axis] // 2]
            x_trunc = np.swapaxes(x_trunc, -1, axis)

            X = fft(x, axis=axis, n=dims[axis] // 2)

            Y = np.fft.fft(x, axis=axis, n=dims[axis] // 2)

            x_ = ifft(X, axis=axis, norm=norm)

            if not np.allclose(X, Y) and not scrambled:
                print(
                    '  Failed forward with ndim=%d axis=%d dims=' %
                    (ndim, axis), dims)
                passed = False

            if not np.allclose(x_trunc, x_):
                print(
                    '  Failed backward with ndim=%d axis=%d dims=' %
                    (ndim, axis), dims)
                passed = False

        self.assertTrue(passed)
Exemple #14
0
    def test_fft(self):

        n_tests = 1000
        n_max = 2
        d_max = 100

        norm = 'ortho'
        inplace = True
        scrambled = True

        passed = True

        for i in range(n_tests):
            ndim = np.random.randint(1,high=n_max+1)
            axis = np.random.randint(0,high=ndim)
            dims = np.random.randint(1,high=d_max+1,size=(ndim))

            x = np.random.normal(size=dims) + 1j*np.random.normal(size=dims)

            if inplace:
                X = x.copy()
                fft(X, axis=axis, norm=norm, out=X, scrambled=scrambled)
            else:
                X = fft(x, axis=axis, norm=norm, scrambled=scrambled)

            Y = np.fft.fft(x, axis=axis, norm=norm)

            x_ = ifft(X, axis=axis, norm=norm)

            if not np.allclose(X,Y) and not scrambled:
                print('  Failed forward with ndim=%d axis=%d dims=' % (ndim, axis), dims)
                passed = False

            if not np.allclose(x, x_):
                print('  Failed backward with ndim=%d axis=%d dims=' % (ndim, axis), dims)
                passed = False

        self.assertTrue(passed)
Exemple #15
0
 def ifft(x, n=None, axis=-1, overwrite_input=False, extra_info=None):
     return mkl_fft.ifft(x, n=n, axis=axis, overwrite_x=overwrite_input)
Exemple #16
0
 def ifft(x, n=None, axis=-1, overwrite_input=False, extra_info=None):
     return mkl_fft.ifft(x, n=n, axis=axis, overwrite_x=overwrite_input)
Exemple #17
0
 def FFT_t_shift(self, A):
     if MKL_AVAILABLE:
         return ifftshift(mkl_fft.ifft(fftshift(A)))
     else:
         return ifftshift(scipy.fftpack.ifft(fftshift(A)))
Exemple #18
0
# Ensure Image can be split in blocks by 8 and split it
height = height - height % block
width = width - width % block
hmax = height // block
wmax = width // block

CompIMG = np.zeros((height, width, 3))

# Process every component
for kk in range(3):
    I = img[:height, :width, kk]
    MM = np.array(I, dtype=np.float32)
    CC = np.zeros((height, width))
    for i in range(hmax):
        for j in range(wmax):
            # Splint int 8x8 blocks
            M = MM[block * i: block * (i + 1), block * j: block * (j + 1)]
            # Execute fft
            D = np.real(mkl_fft.fft(M)).reshape((-1, 8))
            # Compress dividing by quantization matrix (most coef are zeros)
            C = np.round(D * Q)
            CC[block * i: block * (i + 1), block * j: block * (j + 1)] = C.copy()
    for i in range(hmax):
        for j in range(wmax):
            # Restore image with ifft
            CompIMG[block * i: block * (i + 1), block * j: block * (j + 1), kk] = np.real(
                mkl_fft.ifft(CC[block * i: block * (i + 1), block * j: block * (j + 1)])).reshape(-1, 8)
# Convert image back to RGB
t.saveImage(CompIMG, file + "_compressedFFT")
t.showResults(file, file + "_compressedFFT")
Exemple #19
0
 def test_array4(self):
     x = self.ad3
     for ax in range(x.ndim):
         f1 = mkl_fft.ifft(x, axis = ax)
         f2 = mkl_fft.fft(f1, axis = ax)
         assert_allclose(f2, x, atol=2e-15)
Exemple #20
0
 def test_matrix6(self):
     x = self.ad2;
     f1 = mkl_fft.ifft(x)
     f2 = mkl_fft.fft(f1)
     assert_allclose(x, f2, atol=1e-10)
Exemple #21
0
 def test_vector8(self):
     "ifft of real array is the same as fft of its complex cast"
     x = self.xd1[3:17:2]
     f1 = mkl_fft.ifft(x)
     f2 = mkl_fft.ifft(x.astype(np.complex128))
     assert_(np.allclose(f1,f2))
Exemple #22
0
def pfourier_multiply(fh, m):
    pos = int(fh.shape[1] // 2 + 1)
    fh[:, pos] = 0.0
    oh = fft(m * ifft(fh))
    oh[:, pos] = 0.0
    return oh
Exemple #23
0
def pifftr(fh):
    pos = int(fh.shape[1] // 2 + 1)
    fh[:, pos] = 0.0
    return ifft(fh).real
Exemple #24
0
def ffourier_multiply(fh, m):
    return fft(m * ifft(fh))
Exemple #25
0
def remove_stripe(img, level, wname='db5', sigma=1.5):
    """
	Suppress horizontal stripe in a sinogram using the Fourier-Wavelet based
	method by Munch et al. [2]_.

	Parameters
	----------
	img : 2d array
		The two-dimensional array representig the image or the sinogram to de-stripe.

	level : int
		The highest decomposition level.

	wname : str, optional
		The wavelet type. Default value is ``db5``

	sigma : float, optional
		The damping factor in the Fourier space. Default value is ``1.5``

	Returns
	-------
	out : 2d array
		The resulting filtered image.

	References
	----------
	.. [2] B. Munch, P. Trtik, F. Marone, M. Stampanoni, Stripe and ring artifact removal with
		   combined wavelet-Fourier filtering, Optics Express 17(10):8567-8591, 2009.
	"""

    nrow, ncol = img.shape

    # wavelet decomposition.
    cH = []
    cV = []
    cD = []

    for i in range(0, level):
        img, (cHi, cVi, cDi) = pywt.dwt2(img, wname)
        cH.append(cHi)
        cV.append(cVi)
        cD.append(cDi)

    # FFT transform of horizontal frequency bands
    for i in range(0, level):
        # FFT
        fcV = fftshift(fft(cV[i], axis=0))
        my, mx = fcV.shape

        # damping of vertical stripe information
        yy2 = (np.arange(-np.floor(my / 2), -np.floor(my / 2) + my))**2
        damp = -np.expm1(-yy2 / (2.0 * (sigma**2)))
        fcV = fcV * np.tile(damp.reshape(damp.size, 1), (1, mx))

        #inverse FFT
        cV[i] = np.real(ifft(ifftshift(fcV), axis=0))

    # wavelet reconstruction
    for i in range(level - 1, -1, -1):
        img = img[0:cH[i].shape[0], 0:cH[i].shape[1]]
        img = pywt.idwt2((img, (cH[i], cV[i], cD[i])), wname)

    return img[0:nrow, 0:ncol]
def conv_sub_1d(x_fft, f, ds):
    '''
    Input
        x_fft: The Fourier transform of the signals to be convolved, 2-d array N x K,
            where K is number of signals.
        f: The filter in the frequency domain (= Fourier transform of the filter).
        ds: The downsampling factor as a power of 2 with respect to x_fft
    Output
        y_ds: the filtered, downsampled signalm in the time domain
    '''

    # periodize filter so that it has the correct resolution
    # j0 = int(np.log2(f.shape[0]/x_fft.shape[0]))
    # f = f.reshape((f.shape[0]//2**j0, 2**j0)).sum(axis = 1)

    sig_length = x_fft.shape[0]

    if type(f) != dict:
        end = len(f)
        f = np.concatenate([
            f[:sig_length // 2],
            [f[sig_length // 2] / 2 + f[end - sig_length // 2] / 2],
            f[end - sig_length // 2 + 1:]
        ])

        # represent filter in matrix form
        f = f[:, np.newaxis] + 0 * 1j
        # print('Inside conv_sub_1d: filter')
        # print(f.shape)
        # print(f[:10,0])

        # Calculate Fourier coefficients
        y_fft = f * x_fft
        #print('Inside conv_sub_1d: y_fft')
        #print(y_fft.shape)
        # print(y_fft[:10,0])

    elif f['type'] == 'fourier_truncated':
        coefft, start = f['coefft'], f['start']

        if len(coefft) > sig_length:
            # filter is larger than signal, lowpass filter & periodize the former
            # create lowpass filter
            start0 = np.mod(start, f['N'])
            nCoeffts0 = len(coefft)

            if start0 + nCoeffts0 - 1 <= f['N']:
                rng = np.arange(start0, nCoeffts0)
            else:
                rng = np.concatenate([
                    np.arange(start0, f['N']),
                    np.arange(nCoeffts0 + start0 - f['N'])
                ])

            lowpass = np.zeros(shape=coefft.shape)
            lowpass[rng < sig_length // 2] = 1
            lowpass[rng == sig_length // 2] = 0.5
            lowpass[rng == f['N'] - sig_length // 2] = 0.5
            lowpass[rng > f['N'] - sig_length // 2] = 1

            coefft = (coefft * lowpass).reshape(
                (sig_length, len(coefft) // sig_length), order='F').sum(axis=1)

        nCoeffts = len(coefft)
        j = int(np.log2(nCoeffts / sig_length))
        start = np.mod(start, x_fft.shape[0])

        if start + nCoeffts <= x_fft.shape[0]:
            # filter support contained in one period, no wrap-around
            y_fft = coefft[:, np.newaxis] * x_fft[start:(nCoeffts + start), :]
        else:
            # filter support wraps around, extract both parts
            y_fft = coefft[:, np.newaxis] * np.concatenate([
                x_fft[start:, :], x_fft[:nCoeffts + start - x_fft.shape[0], :]
            ])

    # Calculate downsampling factor with respect to y_fft
    # Пока в имплементации у нас всегда y_fft.shape[0]=x_fft.shape[0]
    ds_factor = ds + np.log2(y_fft.shape[0] / sig_length)
    #print('Inside conv_sub_1d: dsj: ', ds_factor)

    if ds_factor > 0:
        y_fft = downsample_filter(y_fft, ds_factor=ds_factor)
    elif ds_factor < 0:
        # upsample, so zero-pad in Fourier
        # note that this only happens for fourier_truncated filters, since otherwise
        # filter sizes are always the same as the signal size
        # also, we have to do one-sided padding since otherwise we might break
        # continuity of Fourier transform
        y_fft = np.concatenate([
            y_fft,
            np.zeros(((2**(-ds_factor) - 1) * y_fft.shape[0], y_fft.shape[1]))
        ])

    #print('Inside conv_sub_1d; downsampled y_fft: ')
    #print(y_fft.shape)
    # print(y_fft[:4,0])

    if (type(f) == dict) and (f['type']
                              == 'fourier_truncated') and f['recenter']:
        # result has been shifted in frequency so that the zero fre-
        # quency is actually at -filter.start+1
        y_fft = np.roll(y_fft, f['start'])

    # Calculate inverse Fourier transform
    # Use .T to apply transform along columns (coefficients of 1-d signals)
    # Divede to the 2**(ds_factor/2) to get the same signal magnitude in time domain
    # after downsampling in frequency domain (CHECK TAHT WE SHOULD DEVIDE ifft NOT fft)

    x_filtered_ds = mkl_fft.ifft(y_fft.T).T / (2**(ds_factor / 2))
    # print('Inside conv_sub_1d; x_filtered_ds: ')
    # print(x_filtered_ds.shape)
    # print(x_filtered_ds[:4,0])
    return x_filtered_ds