Added FilterBank class.

Leonardo Robol [2010-03-02 17:44]
Added FilterBank class.
Filename
Filtering/Filtering.py
diff --git a/Filtering/Filtering.py b/Filtering/Filtering.py
index fe0ed71..b046372 100644
--- a/Filtering/Filtering.py
+++ b/Filtering/Filtering.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 #

-from numpy import array, zeros, convolve, dot
+from numpy import array, zeros, convolve, dot, roll

 class AbstractFilter():

@@ -49,3 +49,133 @@ def UpSample(samples):
     s = zeros(2 * len(samples))
     s[::2] = samples
     return array(s)
+
+
+class FilterBank():
+
+    def __init__(self):
+        """Create a new empty filter bank"""
+        self.lowPassFilter = None
+        self.highPassFilter = None
+        self.highPassInverseFilter = None
+        self.lowPassInverseFilter = None
+
+        self.depth = 1
+
+    def SetFilterMatrix(self, filter_matrix):
+        """
+        Set the filter matrix for the filter bank.
+        It must have this shape:
+
+          [ h0 , h1, f0, f1 ]
+
+        Where h0 is the lowPass coefficients vector,
+        h1 the high pass one, f0 the inverse low pass
+        and f1 the inverse high pass.
+        This method can only use FIR filters, if you are
+        looking for more freedom use SetLowPassFilter ()
+        and similar.
+        """
+        self.lowPassFilter = FIR (filter_matrix[0])
+        self.highPassFilter = FIR (filter_matrix[1])
+        self.lowPassInverseFilter = FIR (filter_matrix[2])
+        self.highPassInverseFilter = FIR (filter_matrix[3])
+
+    def _Truncate(self, samples):
+        """
+        Returns the samples truncated to make
+        recursive split possibile
+        (i.e. len(samples) % 2^depth = 0)
+        """
+        toRemove = len(samples) % pow(2,self.depth)
+        if toRemove is 0:
+            return samples
+        else:
+            return samples[:-1 * toRemove]
+
+    def SetDepth(self, depth):
+        """
+        Set the depth of the filter, i.e. how many recursion
+        will be done when filtering and downsampling
+        """
+        self.depth = depth
+
+    def SetLowPassFilter(self, lowpass):
+        """
+        Set the LowPassFilter for the filterbank.
+        It has to be a callable that transform the
+        samples. It will usually be a FIR
+        """
+        self.lowPassFilter = lowpass
+
+    def SetHighPassFilter(self, highpass):
+        """
+        Set the High pass filter. It is usually
+        a FIR but can be a generic callable that
+        returns the filtered samples
+        """
+        self.highPassFilter = highpass
+
+    def SetLowPassInverseFilter(self, lowpass):
+        """
+        Set the LowPass inverse filter to be used
+        in reconstruction.
+        """
+        self.lowPassInverseFilter = lowpass
+
+    def SetHighPassInverseFilter(self, highpass):
+        """
+        Set the HighPass inverse filter to be used
+        in signal reconstruction
+        """
+        self.highPassInverseFilter = highpass
+
+    def Split(self, samples):
+        """
+        Split the samples using the filter provided
+        by the user. It returns an array of samples similar
+        to this:
+
+          [ high, high, high , ... , high, low ]
+
+        that contains the details and the last average.
+        The original signal can be rebuilt collapsing
+        all these downsamples signals with the Rebuild
+        method.
+        """
+
+        samplesArray = []
+        low = self._Truncate(samples)
+
+        # Do the real filtering and downsampling. Store the downsampled
+        # details in the array.
+        for recursion in xrange(1, self.depth):
+            samplesArray.append (DownSample (self.highPassFilter (low)))
+            low = DownSample (self.lowPassFilter (low))
+
+        # In the end append the low downsampled data to the array
+        samplesArray.append (low)
+
+        return samplesArray
+
+    def Rebuild(self, sampleArray):
+        """
+        Rebuild an array of samples obtained by the Split()
+        method.
+        """
+
+        low = sampleArray.pop ()
+
+        # Iterate over the reversed array
+        for high in sampleArray[::-1]:
+            low = self.lowPassInverseFilter (UpSample (low))
+            low += self.highPassInverseFilter (UpSample (high))
+            low = roll(low, -1)
+
+        return low
+
+
+
+
+
+
ViewGit