Exemple #1
0
def test_dwt_coeff_len():
    x = np.array([3, 7, 1, 1, -2, 5, 4, 6])
    w = pywt.Wavelet("sym3")
    ln_modes = [pywt.dwt_coeff_len(len(x), w.dec_len, mode) for mode in pywt.Modes.modes]
    assert_allclose(ln_modes, [6, 6, 6, 6, 6, 6, 4])
    ln_modes = [pywt.dwt_coeff_len(len(x), w, mode) for mode in pywt.Modes.modes]
    assert_allclose(ln_modes, [6, 6, 6, 6, 6, 6, 4])
Exemple #2
0
def compose_wvlt_from_vec(pin, imshape, wavelet='db4', mode='symmetric'):
    #currently limited to square geometry
    w = pywt.Wavelet(wavelet)
    Nl = pywt.dwt_max_level(max(imshape), w.dec_len)
    levlens = [pywt.dwt_coeff_len(max(imshape), w.dec_len, mode=mode)]
    for j in range(1, Nl):
        levlens.append(pywt.dwt_coeff_len(levlens[-1], w.dec_len, mode=mode))
    levlens.append(levlens[-1])
    levlens = levlens[::-1]
    p_wvlt = [
        reshape(array(pin[0:levlens[0]**2], float), (levlens[0], levlens[0]))
    ]
    celem = levlens[0]**2
    for j in range(1, Nl + 1):
        t1 = reshape(array(pin[celem:celem + levlens[j]**2], float),
                     (levlens[j], levlens[j]))
        celem += levlens[j]**2
        t2 = reshape(array(pin[celem:celem + levlens[j]**2], float),
                     (levlens[j], levlens[j]))
        celem += levlens[j]**2
        t3 = reshape(array(pin[celem:celem + levlens[j]**2], float),
                     (levlens[j], levlens[j]))
        celem += levlens[j]**2
        p_wvlt.append((t1, t2, t3))
    return p_wvlt
Exemple #3
0
def test_dwt_coeff_len():
    x = np.array([3, 7, 1, 1, -2, 5, 4, 6])
    w = pywt.Wavelet('sym3')
    ln = pywt.dwt_coeff_len(data_len=len(x), filter_len=w.dec_len, mode='sym')
    assert_(ln == 6)
    ln_modes = [pywt.dwt_coeff_len(len(x), w.dec_len, mode) for mode in
                pywt.MODES.modes]
    assert_allclose(ln_modes, [6, 6, 6, 6, 6, 4])
Exemple #4
0
def test_dwt_coeff_len():
    x = np.array([3, 7, 1, 1, -2, 5, 4, 6])
    w = pywt.Wavelet('sym3')
    ln_modes = [pywt.dwt_coeff_len(len(x), w.dec_len, mode) for mode in
                pywt.Modes.modes]
    assert_allclose(ln_modes, [6, 6, 6, 6, 6, 4])
    ln_modes = [pywt.dwt_coeff_len(len(x), w, mode) for mode in
                pywt.Modes.modes]
    assert_allclose(ln_modes, [6, 6, 6, 6, 6, 4])
def test_dwt_coeff_len():
    x = np.array([3, 7, 1, 1, -2, 5, 4, 6])
    w = pywt.Wavelet('sym3')
    ln = pywt.dwt_coeff_len(data_len=len(x), filter_len=w.dec_len, mode='sym')
    assert_(ln == 6)
    ln_modes = [
        pywt.dwt_coeff_len(len(x), w.dec_len, mode)
        for mode in pywt.MODES.modes
    ]
    assert_allclose(ln_modes, [6, 6, 6, 6, 6, 4])
def test_dwt_coeff_len():
    x = np.array([3, 7, 1, 1, -2, 5, 4, 6])
    w = pywt.Wavelet('sym3')
    ln_modes = [pywt.dwt_coeff_len(len(x), w.dec_len, mode) for mode in
                pywt.Modes.modes]

    expected_result = [6, ] * len(pywt.Modes.modes)
    expected_result[pywt.Modes.modes.index('periodization')] = 4

    assert_allclose(ln_modes, expected_result)
    ln_modes = [pywt.dwt_coeff_len(len(x), w, mode) for mode in
                pywt.Modes.modes]
    assert_allclose(ln_modes, expected_result)
Exemple #7
0
def test_dwt_coeff_len():
    x = np.array([3, 7, 1, 1, -2, 5, 4, 6])
    w = pywt.Wavelet('sym3')
    ln_modes = [pywt.dwt_coeff_len(len(x), w.dec_len, mode) for mode in
                pywt.Modes.modes]

    expected_result = [6, ] * len(pywt.Modes.modes)
    expected_result[pywt.Modes.modes.index('periodization')] = 4

    assert_allclose(ln_modes, expected_result)
    ln_modes = [pywt.dwt_coeff_len(len(x), w, mode) for mode in
                pywt.Modes.modes]
    assert_allclose(ln_modes, expected_result)
Exemple #8
0
 def full_coeff_len(datalen, filtlen, mode):
     max_level = pywt.dwt_max_level(datalen, filtlen)
     total_len = 0
     for i in xrange(max_level):
         datalen = pywt.dwt_coeff_len(datalen, filtlen, mode)
         total_len += datalen 
     return total_len + datalen
    def __init__(self, depth, init_wavelet, scales, p_drop=0.5):
        super().__init__()
        print("wavelet dropout:", p_drop)
        self.scales = scales
        self.wavelet = init_wavelet
        self.mode = "zero"
        self.coefficient_len_lst = [depth]
        for _ in range(scales):
            self.coefficient_len_lst.append(
                pywt.dwt_coeff_len(
                    self.coefficient_len_lst[-1],
                    init_wavelet.dec_lo.shape[-1],
                    self.mode,
                ))
        self.coefficient_len_lst = self.coefficient_len_lst[1:]
        self.coefficient_len_lst.append(self.coefficient_len_lst[-1])

        wave_depth = np.sum(self.coefficient_len_lst)
        self.depth = depth
        self.diag_vec_s = Parameter(
            torch.from_numpy(np.ones(depth, np.float32)))
        self.diag_vec_g = Parameter(
            torch.from_numpy(np.ones(wave_depth, np.float32)))
        self.diag_vec_b = Parameter(
            torch.from_numpy(np.ones(depth, np.float32)))
        perm = np.random.permutation(np.eye(wave_depth, dtype=np.float32))
        self.perm = Parameter(torch.from_numpy(perm), requires_grad=False)

        self.drop_s = torch.nn.Dropout(p=p_drop)
        self.drop_g = torch.nn.Dropout(p=p_drop)
        self.drop_b = torch.nn.Dropout(p=p_drop)
Exemple #10
0
def func_IDWT(I_W, level=LEVEL, wavelet=BIOR, mode=MODE):
    '''
    小波逆变换,将输入的小波参数,根据小波变换等级,小波类型,变换模式将小波参数逆变换为原图像
    IDWT
    I_W : numpy array
    level : wavelet level
    wavelet : wavelet type
    mode : wavelet mode
    '''
    width = I_W.shape[0]
    height = I_W.shape[0]
    S = [-1] * level
    current_size = width
    for i in range(level):
        current_size = pywt.dwt_coeff_len(current_size, pywt.Wavelet(BIOR),
                                          MODE)
        S[i] = current_size
    S.reverse()
    for current_size in S:
        #  current_size = S[i]
        LL = I_W[0:current_size, 0:current_size]
        LH = I_W[0:current_size, current_size:2 * current_size]
        HL = I_W[current_size:2 * current_size, 0:current_size]
        HH = I_W[current_size:2 * current_size, current_size:2 * current_size]
        coeffs = [LL, [LH, HL, HH]]
        I_W[0:2 * current_size,
            0:2 * current_size] = pywt.idwt2(coeffs, wavelet, MODE)
    return I_W
def compose_vec_from_wvlt(p_wvlt,imshape,wavelet='db4',mode='symmetric'):
    #currently limited to square geometry
    w=pywt.Wavelet(wavelet)
    Nl=pywt.dwt_max_level(max(imshape),w.dec_len)
    levlens=[pywt.dwt_coeff_len(max(imshape),w.dec_len,mode=mode)] 
    for j in range(1,Nl):
        levlens.append( pywt.dwt_coeff_len(levlens[-1],w.dec_len,mode=mode) )
    levlens.append(levlens[-1])
    levlens=levlens[::-1]
    Na=sum(levlens)
    ret_arr = empty( (Na*Na,),float)
    ret_arr[0:levlens[0]**2] = ravel(p_wvlt[0])
    celem=levlens[0]**2
    for j in range(1,Nl+1):
        for k in range(3):
           ret_arr[celem:celem+levlens[j]**2]=ravel(p_wvlt[j][k])
           celem+=levlens[j]**2
    return ret_arr
Exemple #12
0
def compose_vec_from_wvlt(p_wvlt, imshape, wavelet='db4', mode='symmetric'):
    #currently limited to square geometry
    w = pywt.Wavelet(wavelet)
    Nl = pywt.dwt_max_level(max(imshape), w.dec_len)
    levlens = [pywt.dwt_coeff_len(max(imshape), w.dec_len, mode=mode)]
    for j in range(1, Nl):
        levlens.append(pywt.dwt_coeff_len(levlens[-1], w.dec_len, mode=mode))
    levlens.append(levlens[-1])
    levlens = levlens[::-1]
    Na = sum(levlens)
    ret_arr = empty((Na * Na, ), float)
    ret_arr[0:levlens[0]**2] = ravel(p_wvlt[0])
    celem = levlens[0]**2
    for j in range(1, Nl + 1):
        for k in range(3):
            ret_arr[celem:celem + levlens[j]**2] = ravel(p_wvlt[j][k])
            celem += levlens[j]**2
    return ret_arr
Exemple #13
0
    def full_coeff_len(datalen, filtlen, mode):
        max_level = wt.dwt_max_level(datalen, filtlen)
        total_len = 0

        for i in xrange(max_level):
            datalen = wt.dwt_coeff_len(datalen, filtlen, mode)
            total_len += datalen

        return total_len + datalen
def compose_wvlt_from_vec(pin,imshape,wavelet='db4',mode='symmetric'):
    #currently limited to square geometry
    w=pywt.Wavelet(wavelet)
    Nl=pywt.dwt_max_level(max(imshape),w.dec_len)
    levlens=[pywt.dwt_coeff_len(max(imshape),w.dec_len,mode=mode)] 
    for j in range(1,Nl):
        levlens.append( pywt.dwt_coeff_len(levlens[-1],w.dec_len,mode=mode) )
    levlens.append(levlens[-1])
    levlens=levlens[::-1]
    p_wvlt=[reshape(array(pin[0:levlens[0]**2],float),(levlens[0],levlens[0]))]
    celem=levlens[0]**2
    for j in range(1,Nl+1):
        t1=reshape(array(pin[celem:celem+levlens[j]**2],float),(levlens[j],levlens[j]))
        celem+=levlens[j]**2
        t2=reshape(array(pin[celem:celem+levlens[j]**2],float),(levlens[j],levlens[j]))
        celem+=levlens[j]**2
        t3=reshape(array(pin[celem:celem+levlens[j]**2],float),(levlens[j],levlens[j]))
        celem+=levlens[j]**2
        p_wvlt.append( (t1,t2,t3) )
    return p_wvlt
Exemple #15
0
 def compute_coeff_no(self, init_length):
     """
     Compute the number of resulting wavelet coefficients.
     @param init_length: length of the input signal vector.
     """
     lengths = [init_length]
     for J in range(self.scales):
         lengths.append(
             pywt.dwt_coeff_len(lengths[-1], self.dec_lo.shape[-1],
                                self.mode))
     lengths.append(lengths[-1])
     return lengths[1:]
def wavelet_BSS(data):
	raw = data
	tp,channels = raw.shape
	wv = pywt.Wavelet('dmey')
	reduced_tp =  int(pywt.dwt_coeff_len(data_len=tp, filter_len=wv.dec_len, mode='symmetric'))
	WT = np.zeros((reduced_tp,channels-1))
	#coeff = np.zeros((22)) #coeffcients from wavelet transformation
	coeff = np.zeros((reduced_tp,channels-1))
	for c in range(channels-1): #exclude the markers
		A,B = wavelet_trans(raw[:,c],wv)
		WT[:,c] = A
    #coeff[c] = B
		coeff[:,c] = B
	n=19  #general neurology techniques say to keep as many channels as possible
	#Essentially, remove the noisiest channel
	#The remaining channels will be cleaned
	#
	Z = WT  #Define source space as wavelet data
	ica = FastICA(n_components = n-1,whiten=True)  #use all components but one
	Z_ = ica.fit_transform(Z)   #Estimated Source Space
	A_ = ica.mixing_            #Retrieve estimated mixing matrix with reduced dimension
	W_p = np.linalg.pinv(A_)    #forced inverse of modified mixing matrix is the unmixing matrix
	#X_filt = np.matmul(Z_,A_)
	####create cleaned stack with outlier_detection####
	weights = np.zeros((reduced_tp,Z_.shape[1]))
	stacks = np.zeros((reduced_tp,Z_.shape[1]))


	for c_ in range(Z_.shape[1]):
		inp = Z_[:,c_]
		weights[:,c_],stacks[:,c_] = outlier_detection(inp)


	stacks = robust_referencing(stacks,weights)

	cleaned_Z_ = stacks.reshape((Z_.shape[0],Z_.shape[1]))
	inv_cleaned_Z_ = ica.inverse_transform(cleaned_Z_)

	inv_wavelet_cleaned_ica = np.zeros((tp,channels-1))


	for c in range(channels-1): #exclude the markers
		cA = inv_cleaned_Z_[:,c]
		cD = coeff[:,c]
		inv_data = inverse_wavelet(cA,cD)
		inv_wavelet_cleaned_ica[:,c] = inv_data

	return inv_wavelet_cleaned_ica;
def quad_afb2d(x, cols, rows, mode='zero', split=True, stride=2):
    """ Does a single level 2d wavelet decomposition of an input. Does separate
    row and column filtering by two calls to
    :py:func:`pytorch_wavelets.dwt.lowlevel.afb1d`

    Inputs:
        x (torch.Tensor): Input to decompose
        filts (list of ndarray or torch.Tensor): If a list of tensors has been
            given, this function assumes they are in the right form (the form
            returned by
            :py:func:`~pytorch_wavelets.dwt.lowlevel.prep_filt_afb2d`).
            Otherwise, this function will prepare the filters to be of the right
            form by calling
            :py:func:`~pytorch_wavelets.dwt.lowlevel.prep_filt_afb2d`.
        mode (str): 'zero', 'symmetric', 'reflect' or 'periodization'. Which
            padding to use. If periodization, the output size will be half the
            input size.  Otherwise, the output size will be slightly larger than
            half.
    """
    x = x / 2
    C = x.shape[1]
    cols = torch.cat([cols] * C, dim=0)
    rows = torch.cat([rows] * C, dim=0)

    if mode == 'per' or mode == 'periodization':
        # Do column filtering
        L = cols.shape[2]
        L2 = L // 2
        if x.shape[2] % 2 == 1:
            x = torch.cat((x, x[:, :, -1:]), dim=2)
        N2 = x.shape[2] // 2
        x = roll(x, -L2, dim=2)
        pad = (L - 1, 0)
        lohi = F.conv2d(x, cols, padding=pad, stride=(stride, 1), groups=C)
        lohi[:, :, :L2] = lohi[:, :, :L2] + lohi[:, :, N2:N2 + L2]
        lohi = lohi[:, :, :N2]

        # Do row filtering
        L = rows.shape[3]
        L2 = L // 2
        if lohi.shape[3] % 2 == 1:
            lohi = torch.cat((lohi, lohi[:, :, :, -1:]), dim=3)
        N2 = x.shape[3] // 2
        lohi = roll(lohi, -L2, dim=3)
        pad = (0, L - 1)
        w = F.conv2d(lohi, rows, padding=pad, stride=(1, stride), groups=8 * C)
        w[:, :, :, :L2] = w[:, :, :, :L2] + w[:, :, :, N2:N2 + L2]
        w = w[:, :, :, :N2]
    elif mode == 'zero':
        # Do column filtering
        N = x.shape[2]
        L = cols.shape[2]
        outsize = pywt.dwt_coeff_len(N, L, mode='zero')
        p = 2 * (outsize - 1) - N + L

        # Sadly, pytorch only allows for same padding before and after, if
        # we need to do more padding after for odd length signals, have to
        # prepad
        if p % 2 == 1:
            x = F.pad(x, (0, 0, 0, 1))
        pad = (p // 2, 0)
        # Calculate the high and lowpass
        lohi = F.conv2d(x, cols, padding=pad, stride=(stride, 1), groups=C)

        # Do row filtering
        N = lohi.shape[3]
        L = rows.shape[3]
        outsize = pywt.dwt_coeff_len(N, L, mode='zero')
        p = 2 * (outsize - 1) - N + L
        if p % 2 == 1:
            lohi = F.pad(lohi, (0, 1, 0, 0))
        pad = (0, p // 2)
        w = F.conv2d(lohi, rows, padding=pad, stride=(1, stride), groups=8 * C)
    elif mode == 'symmetric' or mode == 'reflect':
        # Do column filtering
        N = x.shape[2]
        L = cols.shape[2]
        outsize = pywt.dwt_coeff_len(N, L, mode=mode)
        p = 2 * (outsize - 1) - N + L
        x = mypad(x, pad=(0, 0, p // 2, (p + 1) // 2), mode=mode)
        lohi = F.conv2d(x, cols, stride=(stride, 1), groups=C)

        # Do row filtering
        N = lohi.shape[3]
        L = rows.shape[3]
        outsize = pywt.dwt_coeff_len(N, L, mode=mode)
        p = 2 * (outsize - 1) - N + L
        lohi = mypad(lohi, pad=(p // 2, (p + 1) // 2, 0, 0), mode=mode)
        w = F.conv2d(lohi, rows, stride=(1, stride), groups=8 * C)
    else:
        raise ValueError("Unkown pad type: {}".format(mode))

    y = w.view((w.shape[0], C, 4, 4, w.shape[-2], w.shape[-1]))
    yl = y[:, :, :, 0]
    yh = y[:, :, :, 1:]
    deg75r, deg105i = pm(yh[:, :, 0, 0], yh[:, :, 3, 0])
    deg105r, deg75i = pm(yh[:, :, 1, 0], yh[:, :, 2, 0])
    deg15r, deg165i = pm(yh[:, :, 0, 1], yh[:, :, 3, 1])
    deg165r, deg15i = pm(yh[:, :, 1, 1], yh[:, :, 2, 1])
    deg135r, deg45i = pm(yh[:, :, 0, 2], yh[:, :, 3, 2])
    deg45r, deg135i = pm(yh[:, :, 1, 2], yh[:, :, 2, 2])
    yhr = torch.stack((deg15r, deg45r, deg75r, deg105r, deg135r, deg165r),
                      dim=1)
    yhi = torch.stack((deg15i, deg45i, deg75i, deg105i, deg135i, deg165i),
                      dim=1)
    yh = torch.stack((yhr, yhi), dim=-1)

    yl_rowa = torch.stack((yl[:, :, 1], yl[:, :, 0]), dim=-1)
    yl_rowb = torch.stack((yl[:, :, 3], yl[:, :, 2]), dim=-1)
    yl_rowa = yl_rowa.view(yl.shape[0], C, yl.shape[-2], yl.shape[-1] * 2)
    yl_rowb = yl_rowb.view(yl.shape[0], C, yl.shape[-2], yl.shape[-1] * 2)
    z = torch.stack((yl_rowb, yl_rowa), dim=-2)
    yl = z.view(yl.shape[0], C, yl.shape[-2] * 2, yl.shape[-1] * 2)

    return yl.contiguous(), yh
def quad_afb2d_nonsep(x, filts, mode='zero'):
    """ Does a 1 level 2d wavelet decomposition of an input. Doesn't do separate
    row and column filtering.

    Inputs:
        x (torch.Tensor): Input to decompose
        filts (list or torch.Tensor): If a list is given, should be the low and
            highpass filter banks. If a tensor is given, it should be of the
            form created by
            :py:func:`pytorch_wavelets.dwt.lowlevel.prep_filt_afb2d_nonsep`
        mode (str): 'zero', 'symmetric', 'reflect' or 'periodization'. Which
            padding to use. If periodization, the output size will be half the
            input size.  Otherwise, the output size will be slightly larger than
            half.
    """
    C = x.shape[1]
    Ny = x.shape[2]
    Nx = x.shape[3]

    # Check the filter inputs
    f = torch.cat([filts] * C, dim=0)
    Ly = f.shape[2]
    Lx = f.shape[3]

    if mode == 'periodization' or mode == 'per':
        if x.shape[2] % 2 == 1:
            x = torch.cat((x, x[:, :, -1:]), dim=2)
            Ny += 1
        if x.shape[3] % 2 == 1:
            x = torch.cat((x, x[:, :, :, -1:]), dim=3)
            Nx += 1
        pad = (Ly - 1, Lx - 1)
        stride = (2, 2)
        x = roll(roll(x, -Ly // 2, dim=2), -Lx // 2, dim=3)
        y = F.conv2d(x, f, padding=pad, stride=stride, groups=C)
        y[:, :, :Ly // 2] += y[:, :, Ny // 2:Ny // 2 + Ly // 2]
        y[:, :, :, :Lx // 2] += y[:, :, :, Nx // 2:Nx // 2 + Lx // 2]
        y = y[:, :, :Ny // 2, :Nx // 2]
    elif mode == 'zero' or mode == 'symmetric' or mode == 'reflect':
        # Calculate the pad size
        out1 = pywt.dwt_coeff_len(Ny, Ly, mode=mode)
        out2 = pywt.dwt_coeff_len(Nx, Lx, mode=mode)
        p1 = 2 * (out1 - 1) - Ny + Ly
        p2 = 2 * (out2 - 1) - Nx + Lx
        if mode == 'zero':
            # Sadly, pytorch only allows for same padding before and after, if
            # we need to do more padding after for odd length signals, have to
            # prepad
            if p1 % 2 == 1 and p2 % 2 == 1:
                x = F.pad(x, (0, 1, 0, 1))
            elif p1 % 2 == 1:
                x = F.pad(x, (0, 0, 0, 1))
            elif p2 % 2 == 1:
                x = F.pad(x, (0, 1, 0, 0))
            # Calculate the high and lowpass
            y = F.conv2d(x, f, padding=(p1 // 2, p2 // 2), stride=2, groups=C)
        elif mode == 'symmetric' or mode == 'reflect':
            pad = (p2 // 2, (p2 + 1) // 2, p1 // 2, (p1 + 1) // 2)
            x = mypad(x, pad=pad, mode=mode)
            y = F.conv2d(x, f, stride=2, groups=C)
    else:
        raise ValueError("Unkown pad type: {}".format(mode))

    y = y.reshape((y.shape[0], C, 4, y.shape[-2], y.shape[-1]))
    yl = y[:, :, 0].contiguous()
    yh = y[:, :, 1:].contiguous()
    return yl, yh
Exemple #19
0
haar = pywt.Wavelet('haar')
db = pywt.Wavelet('db2')

# returns [decomposition, reconstruction] x [low, high]
# reconstruction seem to be the ones i'm familiar with
haar.filter_bank

scale_vals, wavelet_vals, x_vals = haar.wavefun()
plt.plot(x_vals, scale_vals)
plt.show()
plt.plot(x_vals, wavelet_vals)
plt.show()

# length of the coefficients
print pywt.dwt_coeff_len(x.shape[0], haar, "sym")
print pywt.dwt_coeff_len(8, 2, "sym")

# Maximum useful level of decomposition for
# This is currently logged as a bug
print pywt.dwt_max_level(x.shape[0], haar.dec_len)

coeffs3 = pywt.wavedec(x, haar, mode='sym', level=3)

# Let's see if I can recover the c(1) = (0, 2)
coeffs2 = pywt.wavedec(x, haar, mode='sym', level=2)
decimated = coeffs[0]

# http://wavelets.pybytes.com/wavelet/db2/
scale_vals, wavelet_vals, x_vals = db.wavefun()
plt.plot(x_vals, scale_vals)
Exemple #20
0
def afb1d(x, h0, h1, mode='zero', dim=-1):
    """ 1D analysis filter bank (along one dimension only) of an image

    Inputs:
        x (tensor): 4D input with the last two dimensions the spatial input
        h0 (tensor): 4D input for the lowpass filter. Should have shape (1, 1,
            h, 1) or (1, 1, 1, w)
        h1 (tensor): 4D input for the highpass filter. Should have shape (1, 1,
            h, 1) or (1, 1, 1, w)
        mode (str): padding method
        dim (int) - dimension of filtering. d=2 is for a vertical filter (called
            column filtering but filters across the rows). d=3 is for a
            horizontal filter, (called row filtering but filters across the
            columns).

    Returns:
        lohi: lowpass and highpass subbands concatenated along the channel
            dimension
    """
    C = x.shape[1]
    # Convert the dim to positive
    d = dim % 4
    s = (2, 1) if d == 2 else (1, 2)
    N = x.shape[d]
    # If h0, h1 are not tensors, make them. If they are, then assume that they
    # are in the right order
    if not isinstance(h0, torch.Tensor):
        h0 = torch.tensor(np.copy(np.array(h0).ravel()[::-1]),
                          dtype=torch.float, device=x.device)
    if not isinstance(h1, torch.Tensor):
        h1 = torch.tensor(np.copy(np.array(h1).ravel()[::-1]),
                          dtype=torch.float, device=x.device)
    L = h0.numel()
    L2 = L // 2
    shape = [1, 1, 1, 1]
    shape[d] = L
    # If h aren't in the right shape, make them so
    if h0.shape != tuple(shape):
        h0 = h0.reshape(*shape)
    if h1.shape != tuple(shape):
        h1 = h1.reshape(*shape)
    h = torch.cat([h0, h1] * C, dim=0)

    if mode == 'per' or mode == 'periodization':
        if x.shape[dim] % 2 == 1:
            if d == 2:
                x = torch.cat((x, x[:, :, -1:]), dim=2)
            else:
                x = torch.cat((x, x[:, :, :, -1:]), dim=3)
            N += 1
        x = roll(x, -L2, dim=d)
        pad = (L - 1, 0) if d == 2 else (0, L - 1)
        lohi = F.conv2d(x, h, padding=pad, stride=s, groups=C)
        N2 = N // 2
        if d == 2:
            lohi[:, :, :L2] = lohi[:, :, :L2] + lohi[:, :, N2:N2 + L2]
            lohi = lohi[:, :, :N2]
        else:
            lohi[:, :, :, :L2] = lohi[:, :, :, :L2] + lohi[:, :, :, N2:N2 + L2]
            lohi = lohi[:, :, :, :N2]
    else:
        # Calculate the pad size
        outsize = pywt.dwt_coeff_len(N, L, mode=mode)
        p = 2 * (outsize - 1) - N + L
        if mode == 'zero':
            # Sadly, pytorch only allows for same padding before and after, if
            # we need to do more padding after for odd length signals, have to
            # prepad
            if p % 2 == 1:
                pad = (0, 0, 0, 1) if d == 2 else (0, 1, 0, 0)
                x = F.pad(x, pad)
            pad = (p // 2, 0) if d == 2 else (0, p // 2)
            # Calculate the high and lowpass
            lohi = F.conv2d(x, h, padding=pad, stride=s, groups=C)
        elif mode == 'symmetric' or mode == 'reflect' or mode == 'periodic':
            pad = (0, 0, p // 2, (p + 1) // 2) if d == 2 else (p // 2, (p + 1) // 2, 0, 0)
            x = mypad(x, pad=pad, mode=mode)
            lohi = F.conv2d(x, h, stride=s, groups=C)
        else:
            raise ValueError("Unkown pad type: {}".format(mode))

    return lohi
Exemple #21
0
def coeff_size_list(shape, nscales, wbasis, mode):
    """Construct a size list from given wavelet coefficients.

    Related to 1D, 2D and 3D multidimensional wavelet transforms that utilize
    `PyWavelets
    <http://www.pybytes.com/pywavelets/>`_.

    Parameters
    ----------
    shape : `tuple`
        Number of pixels/voxels in the image. Its length must be 1, 2 or 3.

    nscales : `int`
        Number of scales in the multidimensional wavelet
        transform.  This parameter is checked against the maximum number of
        scales returned by ``pywt.dwt_max_level``. For more information
        see the `PyWavelets documentation on the maximum level of scales
        <http://www.pybytes.com/pywavelets/ref/\
dwt-discrete-wavelet-transform.html#maximum-decomposition-level\
-dwt-max-level>`_.

    wbasis : ``pywt.Wavelet``
        Selected wavelet basis. For more information see the
        `PyWavelets documentation on wavelet bases
        <http://www.pybytes.com/pywavelets/ref/wavelets.html>`_.

    mode : `str`
        Signal extention mode. Possible extension modes are

        'zpd': zero-padding -- signal is extended by adding zero samples

        'cpd': constant padding -- border values are replicated

        'sym': symmetric padding -- signal extension by mirroring samples

        'ppd': periodic padding -- signal is trated as a periodic one

        'sp1': smooth padding -- signal is extended according to the
        first derivatives calculated on the edges (straight line)

        'per': periodization -- like periodic-padding but gives the
        smallest possible number of decomposition coefficients.

    Returns
    -------
    size_list : `list`
        A list containing the sizes of the wavelet (approximation
        and detail) coefficients at different scaling levels:

        ``size_list[0]`` = size of approximation coefficients at
        the coarsest level

        ``size_list[1]`` = size of the detail coefficients at the
        coarsest level

        ...

        ``size_list[N]`` = size of the detail coefficients at the
        finest level

        ``size_list[N+1]`` = size of the original image

        ``N`` = number of scaling levels = nscales
    """
    if len(shape) not in (1, 2, 3):
        raise ValueError('shape must have length 1, 2 or 3, got {}.'
                         ''.format(len(shape)))

    max_level = pywt.dwt_max_level(shape[0], filter_len=wbasis.dec_len)
    if nscales > max_level:
        raise ValueError('Too many scaling levels, got {}, maximum useful'
                         ' level is {}'
                         ''.format(nscales, max_level))

    # dwt_coeff_len calculates the number of coefficients at the next
    # scaling level given the input size, the length of the filter and
    # the applied mode.
    # We use this in the following way (per dimension):
    # - length[0] = original data length
    # - length[n+1] = dwt_coeff_len(length[n], ...)
    # - until n = nscales
    size_list = [shape]
    for scale in range(nscales):
        shp = tuple(pywt.dwt_coeff_len(n, filter_len=wbasis.dec_len, mode=mode)
                    for n in size_list[scale])
        size_list.append(shp)

    # Add a duplicate of the last entry for the approximation coefficients
    size_list.append(size_list[-1])

    # We created the list in reversed order compared to what pywt expects
    size_list.reverse()
    return size_list
Exemple #22
0
def pywt_coeff_shapes(shape, wavelet, nlevels, mode):
    """Return a list of coefficient shapes in the specified transform.

    The wavelet transform specified by ``wavelet``, ``nlevels`` and
    ``mode`` produces a sequence of approximation and detail
    coefficients. This function computes the shape of those
    coefficient arrays and returns them as a list.

    Parameters
    ----------
    shape : sequence
        Shape of an input to the transform.
    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.
    nlevels : positive int
        Number of scaling levels to be used in the decomposition. The
        maximum number of levels can be calculated with
        `pywt.dwt_max_level`.
    mode : string, optional
        PyWavelets style signal extension mode. See `signal extension modes`_
        for available options.

    Returns
    -------
    shapes : list
        The shapes of the approximation and detail coefficients at
        different scaling levels in the following order:

            ``[shape_aN, shape_DN, ..., shape_D1]``

        Here, ``shape_aN`` is the shape of the N-th level approximation
        coefficient array, and ``shape_Di`` is the shape of all
        i-th level detail coefficients.

    See Also
    --------
    pywt.dwt_coeff_len : function used to determine coefficient sizes at
        each scaling level

    Examples
    --------
    Determine the coefficient shapes for 2 scaling levels in 3 dimensions
    with zero-padding. Approximation coefficient shape comes first, then
    the level-2 detail coefficient and last the level-1 detail coefficient:

    >>> pywt_coeff_shapes(shape=(16, 17, 18), wavelet='db2', nlevels=2,
    ...                   mode='zero')
    [(6, 6, 6), (6, 6, 6), (9, 10, 10)]

    References
    ----------
    .. _signal extension modes:
       https://pywavelets.readthedocs.io/en/latest/ref/signal-extension-\
modes.html
    """
    shape = tuple(shape)
    if any(int(s) != s for s in shape):
        raise ValueError('`shape` may only contain integers, got {}'
                         ''.format(shape))
    wavelet = pywt_wavelet(wavelet)

    nlevels, nlevels_in = int(nlevels), nlevels
    if nlevels_in != nlevels:
        raise ValueError('`nlevels` must be integer, got {}'
                         ''.format(nlevels_in))
    # TODO: adapt for axes
    for i, n in enumerate(shape):
        max_levels = pywt.dwt_max_level(n, wavelet.dec_len)
        if max_levels == 0:
            raise ValueError('in axis {}: data size {} too small for '
                             'transform, results in maximal `nlevels` of 0'
                             ''.format(i, n))
        if not 0 < nlevels <= max_levels:
            raise ValueError('in axis {}: `nlevels` must satisfy 0 < nlevels '
                             '<= {}, got {}'
                             ''.format(i, max_levels, nlevels))

    mode, mode_in = str(mode).lower(), mode
    if mode not in PYWT_SUPPORTED_MODES:
        raise ValueError("mode '{}' not understood".format(mode_in))

    # Use pywt.dwt_coeff_len to determine the coefficient lengths at each
    # scale recursively. Start with the image shape and use the last created
    # shape for the next step.
    shape_list = [shape]
    for _ in range(nlevels):
        shape = tuple(
            pywt.dwt_coeff_len(n, filter_len=wavelet.dec_len, mode=mode)
            for n in shape_list[-1])
        shape_list.append(shape)

    # Add a duplicate of the last entry for the approximation coefficients
    shape_list.append(shape_list[-1])

    # We created the list in reversed order, reverse it. Remove also the
    # superfluous image shape at the end.
    shape_list.reverse()
    shape_list.pop()
    return shape_list
# Multilevel decomposition using
from pywt import wavedec
cA2, cD2, cD1 = wavedec([1, 2, 3, 4, 3, 2, 1], "db1", level=2)
print(cA2)
print(cD2)
print(cD1)
print()

# Partial Discrete Wavelet Transform data decomposition
# Similar to pywt.dwt, but computes only one set of coefficients.
# Useful when you need only approximation or only details at the given level.
coeffs = pywt.downcoef(part="a",
                       data=[1, 2, 3, 4, 3, 2, 1],
                       wavelet="db1",
                       level=2)
print(coeffs)
print()

# Maximum decomposition level
w = pywt.Wavelet("sym5")
l = pywt.dwt_max_level(data_len=1000, filter_len=w.dec_len)
print(l)
l = pywt.dwt_max_level(data_len=1000, filter_len=w)
print(l)
print()

# Result coefficients length
l = pywt.dwt_coeff_len(data_len=1000, filter_len=w, mode="per")
print(l)
Exemple #24
0
def discrete_wavelet_transform_example():
    x = [3, 7, 1, 1, -2, 5, 4, 6]
    cA, cD = pywt.dwt(x, 'db2')  # Approximation and detail coefficients.

    print('Approximation coefficients =', cA)
    print('Detail coefficients =', cD)

    print('Single level reconstruction of signal =', pywt.idwt(cA, cD, 'db2'))

    #--------------------
    # Pass a Wavelet object instead of the wavelet name and specify signal extension mode (the default is symmetric) for the border effect handling

    w = pywt.Wavelet('sym3')

    # the output coefficients arrays length depends not only on the input data length but also on the :class:Wavelet type (particularly on its filters length that are used in the transformation).
    # If you expected that the output length would be a half of the input data length, well, that's the trade-off that allows for the perfect reconstruction…
    cA, cD = pywt.dwt(x, wavelet=w, mode='constant')

    print('Approximation coefficients =', cA)
    print('Detail coefficients =', cD)

    # To find out what will be the output data size use the dwt_coeff_len() function.
    print(
        'Length of coefficients =',
        int(
            pywt.dwt_coeff_len(data_len=len(x),
                               filter_len=w.dec_len,
                               mode='symmetric')))
    print('Length of coefficients =',
          int(pywt.dwt_coeff_len(len(x), w, 'symmetric')))
    print('Length of coefficients =', len(cA))

    # The periodization (periodization) mode is slightly different from the others.
    # It's aim when doing the DWT transform is to output coefficients arrays that are half of the length of the input data.

    # Knowing that, you should never mix the periodization mode with other modes when doing DWT and IDWT.
    # Otherwise, it will produce invalid results.

    cA, cD = pywt.dwt(x, wavelet=w, mode='periodization')
    print('Single level reconstruction of signal =',
          pywt.idwt(cA, cD, 'sym3', 'symmetric'))  # Invalid mode.
    print('Single level reconstruction of signal =',
          pywt.idwt(cA, cD, 'sym3', 'periodization'))

    # Passing None as one of the coefficient arrays parameters is similar to passing a zero-filled array.
    print('Single level reconstruction of signal =',
          pywt.idwt([1, 2, 0, 1], None, 'db2', 'symmetric'))
    print('Single level reconstruction of signal =',
          pywt.idwt([1, 2, 0, 1], [0, 0, 0, 0], 'db2', 'symmetric'))
    print('Single level reconstruction of signal =',
          pywt.idwt(None, [1, 2, 0, 1], 'db2', 'symmetric'))
    print('Single level reconstruction of signal =',
          pywt.idwt([0, 0, 0, 0], [1, 2, 0, 1], 'db2', 'symmetric'))

    # Only one argument at a time can be None.
    try:
        print('Single level reconstruction of signal =',
              pywt.idwt(None, None, 'db2', 'symmetric'))
    except ValueError as ex:
        print('Invalid coefficient parameter.')

    # When doing the IDWT transform, usually the coefficient arrays must have the same size.
    try:
        pywt.idwt([1, 2, 3, 4, 5], [1, 2, 3, 4], 'db2', 'symmetric')
    except ValueError as ex:
        print('Invalid size of coefficients arrays.')

    # Not every coefficient array can be used in IDWT.
    try:
        pywt.idwt([1, 2, 4], [4, 1, 3], 'db4', 'symmetric')
    except ValueError as ex:
        print('Invalid coefficient arrays length.')

    print('Coefficient length =',
          int(pywt.dwt_coeff_len(1,
                                 pywt.Wavelet('db4').dec_len, 'symmetric')))
Exemple #25
0
>>> w = pywt.Wavelet('sym3')

>>> cA, cD = pywt.dwt(x, wavelet=w, mode='cpd')

>>> print cA

[ 4.38354585  3.80302657  7.31813271 -0.58565539  4.09727044  7.81994027]

>>> print cD

[-1.33068221 -2.78795192 -3.16825651 -0.67715519 -0.09722957 -0.07045258]

注意这里输出的系数数组长度不只跟输入数据的长度有关,还和Wavelet类型有关(特别是它所使用的滤波器长度)。
如果想查看输出数据的长度可以使用dwt_coeff_len()函数:

>>> pywt.dwt_coeff_len(data_len=len(x), filter_len=w.dec_len, mode='sym')
6
>>> pywt.dwt_coeff_len(len(x), w, 'sym')
6
>>> len(cA)
6

dwt_coeff_len()函数的第三个参数是mode。

>>> pywt.MODES.modes

['zpd', 'cpd', 'sym', 'ppd', 'sp1', 'per']

>>> [pywt.dwt_coeff_len(len(x), w.dec_len, mode) for mode in pywt.MODES.modes]

[6, 6, 6, 6, 6, 4]
Exemple #26
0
def pywt_coeff_shapes(shape, wavelet, nlevels, mode):
    """Return a list of coefficient shapes in the specified transform.

    The wavelet transform specified by ``wavelet``, ``nlevels`` and
    ``mode`` produces a sequence of approximation and detail
    coefficients. This function computes the shape of those
    coefficient arrays and returns them as a list.

    Parameters
    ----------
    shape : sequence
        Shape of an input to the transform.
    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.
    nlevels : positive int
        Number of scaling levels to be used in the decomposition. The
        maximum number of levels can be calculated with
        `pywt.dwt_max_level`.
    mode : string, optional
        PyWavelets style signal extension mode. See `signal extension modes`_
        for available options.

    Returns
    -------
    shapes : list
        The shapes of the approximation and detail coefficients at
        different scaling levels in the following order:

            ``[shape_aN, shape_DN, ..., shape_D1]``

        Here, ``shape_aN`` is the shape of the N-th level approximation
        coefficient array, and ``shape_Di`` is the shape of all
        i-th level detail coefficients.

    See Also
    --------
    pywt.dwt_coeff_len : function used to determine coefficient sizes at
        each scaling level

    Examples
    --------
    Determine the coefficient shapes for 2 scaling levels in 3 dimensions
    with zero-padding. Approximation coefficient shape comes first, then
    the level-2 detail coefficient and last the level-1 detail coefficient:

    >>> pywt_coeff_shapes(shape=(16, 17, 18), wavelet='db2', nlevels=2,
    ...                   mode='zero')
    [(6, 6, 6), (6, 6, 6), (9, 10, 10)]

    References
    ----------
    .. _signal extension modes:
       https://pywavelets.readthedocs.io/en/latest/ref/signal-extension-\
modes.html
    """
    shape = tuple(shape)
    if any(int(s) != s for s in shape):
        raise ValueError('`shape` may only contain integers, got {}'
                         ''.format(shape))
    wavelet = pywt_wavelet(wavelet)

    nlevels, nlevels_in = int(nlevels), nlevels
    if nlevels_in != nlevels:
        raise ValueError('`nlevels` must be integer, got {}'
                         ''.format(nlevels_in))
    # TODO: adapt for axes
    for i, n in enumerate(shape):
        max_levels = pywt.dwt_max_level(n, wavelet.dec_len)
        if max_levels == 0:
            raise ValueError('in axis {}: data size {} too small for '
                             'transform, results in maximal `nlevels` of 0'
                             ''.format(i, n))
        if not 0 < nlevels <= max_levels:
            raise ValueError('in axis {}: `nlevels` must satisfy 0 < nlevels '
                             '<= {}, got {}'
                             ''.format(i, max_levels, nlevels))

    mode, mode_in = str(mode).lower(), mode
    if mode not in PYWT_SUPPORTED_MODES:
        raise ValueError("mode '{}' not understood".format(mode_in))

    # Use pywt.dwt_coeff_len to determine the coefficient lengths at each
    # scale recursively. Start with the image shape and use the last created
    # shape for the next step.
    shape_list = [shape]
    for _ in range(nlevels):
        shape = tuple(pywt.dwt_coeff_len(n, filter_len=wavelet.dec_len,
                                         mode=mode)
                      for n in shape_list[-1])
        shape_list.append(shape)

    # Add a duplicate of the last entry for the approximation coefficients
    shape_list.append(shape_list[-1])

    # We created the list in reversed order, reverse it. Remove also the
    # superfluous image shape at the end.
    shape_list.reverse()
    shape_list.pop()
    return shape_list
Exemple #27
0
 def coeff_len(self, input_length):
     return pywt.dwt_coeff_len(input_length, self.dec_lo.shape[0],
                               self.mode)