简体   繁体   中英

Python: wavelets, problems with PyWavelets

I'm attempting some wavelet analysis on images, and I need some method for multiscale decomposition. I'm experimenting with the PyWavelets package. However, the dwt2 and idwt2 methods only provide a single scale. I could iterate these methods, and apply single scale decomposition to smaller areas of the image; if the result of dwt2 consists of 4 arrays:

---------
| A | B |
---------
| C | D |
---------

then I could apply dwt2 to the subarray A and so on. However, there's a difficulty here in that many wavelets produce arrays bigger than the inputs. Note that on the PyWavelets example page the wavelet used is db1 . But if we try db2 :

>>> import pywt
>>> x = [3, 7, 1, 1, -2, 5, 4, 6]
>>> db2 = pywt.Wavelet('db2')
>>> X = pywt.wavedec(x, db2)
>>> print X[0]
[ 5.65685425  7.39923721  0.22414387  3.33677403  7.77817459]

>>> print X[1][0] 
-2.44948974278

>>> print X[1][1]
-1.60368225335

>>> print X[1][2]
-4.44140056379

So I don't seem to be able to perform multilevel decompositions except with db1 (which is the Haar wavelet).

I know there are various wavelet implementations in other packages, but I don't know if any of them provide robust multiscale decomposition of multidimensional data. What's my best option here?

The issue is that your input vector is very short relative to the support width of the wavelet. The maximum useful level of decomposition for a given input length and filter length is given by:

max_level = floor(log2(input_len / (filter_len - 1)))

max_level is the deepest level at which at least one of the wavelet coefficients will still be correct. In your case the signal length is 8 and the wavelet decomposition filter length ( db2.dec_len ) is 4, so:

max_level = floor(log2(8 / 3))
          = floor(~1.415)

A Haar wavelet has a filter length of 2, giving a maximum depth of 3. PyWavelets provides the convenience function pywt.dwt_max_level() to check this.

You can force any arbitrarily high decomposition level by passing the level= parameter to pywt.wavedec() :

X2 = pywt.wavedec(x, db2, level=10)

print(X2)
# [array([ 132.53206536,  133.27955261,  139.11658525]),
#  array([-0.3417812 ,  1.65856932, -1.31678812]),
#  array([-0.24371917,  1.27639144, -1.03267227]),
#  array([-0.15012416,  0.98850433, -0.83838017]),
#  array([-0.04137053,  0.77800706, -0.73663653]),
#  array([ 0.11632636,  0.63709966, -0.75342601]),
#  array([ 0.38650452,  0.57015757, -0.95666209]),
#  array([ 0.89346983,  0.60133166, -1.49480149]),
#  array([ 0.04651697, -5.29123125,  4.49828673]),
#  array([-1.0669873 , -3.81458256,  1.97307621, -0.0669873 ]),
#  array([-2.44948974, -1.60368225, -4.44140056, -0.41361256,  1.22474487])]

print(pywt.waverec(X2, db2))
# [ 3.  7.  1.  1. -2.  5.  4.  6.]

This is rather pointless, though: you will just get spurious coefficients because there is no longer sufficient overlap between the wavelet filter and the signal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM