头文件:
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * filtercoefs.h * * Some generally used filter coeffcients in wavelet transform. * * Zhang Ming, 2010-03, Xi'an Jiaotong University. *****************************************************************************/ #ifndef COEFFICIENTS_H #define COEFFICIENTS_H #include <vector.h> namespace splab { template<typename Type> void db4Coefs( Vector<Type>&, Vector<Type>&, Vector<Type>&, Vector<Type>& ); #include <filtercoefs-impl.h> } // namespace splab #endif // COEFFICIENTS_H
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * dwt.h * * Discrete Wavelet Transform. * * Class template of discrete wavelet transform, which is designed for * computing the discrete wavelet transform and it's inverse transform. The * wavelet type is specified by parameter "wname". * * The decompse and reconstruction levels are specified by integer "J". The * approximation and detial coefficents are stroed in an 1D vector as * fallowing format: * --------------------------------- * | d1 | d2 | * | * | * | dJ | aJ | * --------------------------------- * The signal's length, detial's and approximation's lengths, are stored * in a vectro as fallow: * -------------------------------------------------- * | L_sig | L_d1 | L_d2 | * | * | * | L_dJ | L_aJ | * -------------------------------------------------- * * Zhang Ming, 2010-03, Xi'an Jiaotong University. *****************************************************************************/ #ifndef DWT_H #define DWT_H #include <string> #include <cstdlib> #include <vector.h> #include <convolution.h> #include <filtercoefs.h> namespace splab { template <typename Type> class DWT { public: DWT( const string &wname ); ~DWT(); Vector<Type> dwt( const Vector<Type> &signal, int J ); Vector<Type> idwt( const Vector<Type> &coefs, int j ); Vector<Type> getApprox( const Vector<Type> &coefs ); Vector<Type> getDetial( const Vector<Type> &coefs, int j ); void setApprox( const Vector<Type> &approx, Vector<Type> &coefs ); void setDetial( const Vector<Type> &detial, Vector<Type> &coefs, int j ); private: // wavelet type string waveType; // decompose and reconstruction filter banks Vector<Type> ld, hd, lr, hr; // length information of coefficients Vector<int> lenInfo; void getFilter( const string &wname ); void lengthInit( int sigLength, int J ); }; // class DWT #include <dwt-impl.h> } // namespace splab #endif // DWT_H
实现文件:
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * filtercoefs-impl.h * * Implementation for filter coeffcients in wavelet transform. * * Zhang Ming, 2010-03, Xi'an Jiaotong University. *****************************************************************************/ /** * Daubichies filters for wavelets with 4 vanishing moments. */ template <typename Type> void db4Coefs( Vector<Type> &ld, Vector<Type> &hd, Vector<Type> &lr, Vector<Type> &hr ) { ld.resize(8); ld[0] = Type(-0.010597401784997); ld[1] = Type(0.032883011666983); ld[2] = Type(0.030841381835987); ld[3] = Type(-0.187034811718881); ld[4] = Type(-0.027983769416984); ld[5] = Type(0.630880767929590); ld[6] = Type(0.714846570552542); ld[7] = Type(0.230377813308855); hd.resize(8); hd[0] = Type(-0.230377813308855); hd[1] = Type(0.714846570552542); hd[2] = Type(-0.630880767929590); hd[3] = Type(-0.027983769416984); hd[4] = Type(0.187034811718881); hd[5] = Type(0.030841381835987); hd[6] = Type(-0.032883011666983); hd[7] = Type(-0.010597401784997); lr = flip(ld); hr = flip(hd); }
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * dwt-impl.h * * Implementation for DWT class. * * Zhang Ming, 2010-03, Xi'an Jiaotong University. *****************************************************************************/ /** * constructors and destructor */ template<typename Type> DWT<Type>::DWT( const string &wname ) : waveType(wname) { if( waveType != "db4" ) { cerr << "No such wavelet type!" << endl; exit(1); } getFilter(wname); } template<typename Type> DWT<Type>::~DWT() { } /** * get coefficients of filter bank */ template<typename Type> inline void DWT<Type>::getFilter( const string &wname ) { if( wname == "db4" ) db4Coefs( ld, hd, lr, hr ); } /** * Initializing the length of coefficients. */ template <typename Type> void DWT<Type>::lengthInit( int sigLength, int J ) { lenInfo.resize(J+2); int na = sigLength, nd = 0, total = 0; lenInfo[0] = sigLength; for( int j=1; j<=J; ++j ) { // detial's length at level j nd = (na+hd.dim()-1)/2; // approx's length at level j na = (na+ld.dim()-1)/2; lenInfo[j] = nd; total += nd; } total += na; lenInfo[J+1] = na; } /** * Get the jth level approximation coefficients. */ template <typename Type> Vector<Type> DWT<Type>::getApprox( const Vector<Type> &coefs ) { int J = lenInfo.dim()-2; Vector<Type> approx(lenInfo[J+1]); int start = 0; for( int i=1; i<=J; ++i ) start += lenInfo[i]; for( int i=0; i<lenInfo[J+1]; ++i ) approx[i] = coefs[i+start]; return approx; } /** * Get the Jth level detial coefficients. */ template <typename Type> Vector<Type> DWT<Type>::getDetial( const Vector<Type> &coefs, int j ) { if( (j < 1) || (j > lenInfo.dim()-2) ) { cerr << "Invalid level for getting detial coefficients!" << endl; return Vector<Type>(0); } Vector<Type> detial(lenInfo[j]); int start = 0; for( int i=1; i<j; ++i ) start += lenInfo[i]; for( int i=0; i<lenInfo[j]; ++i ) detial[i] = coefs[i+start]; return detial; } /** * Set the Jth level approximation coefficients. */ template <typename Type> void DWT<Type>::setApprox( const Vector<Type> &approx, Vector<Type> &coefs ) { int J = lenInfo.dim()-2; if( approx.dim() != lenInfo[J+1] ) { cerr << "Invalid length for setting approximation coefficient!" << endl; return; } // the approximation's start position in the coe int start = 0; for( int i=1; i<=J; ++i ) start += lenInfo[i]; for( int i=0; i<lenInfo[J+1]; ++i ) coefs[i+start] = approx[i]; } /** * Set the jth level's detial coefficients. */ template <typename Type> void DWT<Type>::setDetial( const Vector<Type> &detial, Vector<Type> &coefs, int j ) { if( detial.dim() != lenInfo[j] ) { cerr << "Invalid length for setting detial coefficients!" << endl; return; } // the jth level detial's start position in the coe int start = 0; for( int i=1; i<j; ++i ) start += lenInfo[i]; for( int i=0; i<lenInfo[j]; ++i ) coefs[i+start] = detial[i]; } /** * Doing J levels decompose for input signal "signal". */ template <typename Type> Vector<Type> DWT<Type>::dwt( const Vector<Type> &signal, int J ) { if( (lenInfo.size() != J+2) || (lenInfo[0] != signal.size()) ) { cout << "first" << endl; lengthInit( signal.size(), J ); } // lengthInit( signal.size(), J ); int total = 0; for( int i=1; i<=J+1; ++i ) total += lenInfo[i]; Vector<Type> coefs(total); Vector<Type> approx = signal; Vector<Type> tmp; for( int j=1; j<=J; ++j ) { // high frequency filtering tmp = conv( approx, hd ); // stored the downsampled signal setDetial( dyadDown(tmp,1), coefs, j ); // low frequency filtering tmp = conv( approx, ld ); approx = dyadDown( tmp, 1 ); } setApprox( approx, coefs ); return coefs; } /** * Recover the jth level approximation signal. * The default parameter is "j=0", which means recover the original signal. */ template <typename Type> Vector<Type> DWT<Type>::idwt( const Vector<Type> &coefs, int j ) { if( coefs.size() != (sum(lenInfo)-lenInfo[0]) ) { cerr << "Invalid wavelet coeffcients!" << endl; return Vector<Type>(0); } int J = lenInfo.dim() - 2; if( (j < 0) || (j > J) ) { cerr << "Invalid level for reconstructing signal!" << endl; return Vector<Type>(0); } Vector<Type> signal = getApprox( coefs ); Vector<Type> detial; for( int i=J; i>j; --i ) { detial = getDetial( coefs, i ); // upsampling signal = dyadUp( signal, 0 ); detial = dyadUp( detial, 0 ); // recover the jth approximation signal = conv( signal, lr ) + conv( detial, hr ); // cut off signal = wkeep( signal,lenInfo[i-1],"center" ); } return signal; }
测试代码:
/***************************************************************************** * dwt_test.cpp * * Discrete wavelet transform testing. * * Zhang Ming, 2010-03, Xi'an Jiaotong University. *****************************************************************************/ #define BOUNDS_CHECK #include <iostream> #include <dwt.h> #include <timing.h> using namespace std; using namespace splab; typedef float Type; const int Ls = 1000; int main() { /******************************* [ signal ] ******************************/ Vector<Type> s(Ls); for(int i=0; i<Ls; i++) { if(i<Ls/4) s[i] = 0.0; else if(i<2*Ls/4) s[i] = 1.0; else if(i<3*Ls/4) s[i] = 3.0; else s[i] = 0.0; } /******************************** [ DWT ] ********************************/ int level = 3; DWT<Type> discreteWT("db4"); Timing cnt; double runtime = 0.0; cout << "Taking discrete wavelet transform." << endl; cnt.start(); Vector<Type> coefs = discreteWT.dwt( s, level ); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (s)" << endl << endl; /******************************** [ IDWT ] *******************************/ level = 0; cout << "Taking inverse discrete wavelet transform." << endl; cnt.start(); Vector<Type> x = discreteWT.idwt( coefs, level ); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (s)" << endl << endl; cout << "The relative error is : norm(s-x) / norm(s) = " << norm(s-x)/norm(s) << endl << endl; return 0; }
运行结果:
Taking discrete wavelet transform. first The running time = 0 (s) Taking inverse discrete wavelet transform. The running time = 0 (s) The relative error is : norm(s-x) / norm(s) = 9.26354e-008 Process returned 0 (0x0) execution time : 0.062 s Press any key to continue.