2

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?

ali_m
  • 71,714
  • 23
  • 223
  • 298
Alasdair
  • 1,300
  • 4
  • 16
  • 28

1 Answers1

3

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.

ali_m
  • 71,714
  • 23
  • 223
  • 298