GestureRecognitionToolkit  Version: 1.0 Revision: 04-03-15
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
LowPassFilter.cpp
1 /*
2  GRT MIT License
3  Copyright (c) <2012> <Nicholas Gillian, Media Lab, MIT>
4 
5  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6  and associated documentation files (the "Software"), to deal in the Software without restriction,
7  including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9  subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in all copies or substantial
12  portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15  LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include "LowPassFilter.h"
22 
23 namespace GRT{
24 
25 //Register the LowPassFilter module with the PreProcessing base class
26 RegisterPreProcessingModule< LowPassFilter > LowPassFilter::registerModule("LowPassFilter");
27 
28 LowPassFilter::LowPassFilter(double filterFactor,double gain,UINT numDimensions,double cutoffFrequency,double delta){
29 
30  classType = "LowPassFilter";
31  preProcessingType = classType;
32  debugLog.setProceedingText("[DEBUG LowPassFilter]");
33  errorLog.setProceedingText("[ERROR LowPassFilter]");
34  warningLog.setProceedingText("[WARNING LowPassFilter]");
35  init(filterFactor,gain,numDimensions);
36 
37  if( cutoffFrequency != -1 && delta != -1 ){
38  setCutoffFrequency(cutoffFrequency, delta);
39  }
40 }
41 
43  classType = "LowPassFilter";
44  preProcessingType = classType;
45  debugLog.setProceedingText("[DEBUG LowPassFilter]");
46  errorLog.setProceedingText("[ERROR LowPassFilter]");
47  warningLog.setProceedingText("[WARNING LowPassFilter]");
48  *this = rhs;
49 }
50 
52 
53 }
54 
56  if(this!=&rhs){
57  this->filterFactor = rhs.filterFactor;
58  this->gain = rhs.gain;
59  this->yy = rhs.yy;
61  }
62  return *this;
63 }
64 
65 bool LowPassFilter::deepCopyFrom(const PreProcessing *preProcessing){
66 
67  if( preProcessing == NULL ) return false;
68 
69  if( this->getPreProcessingType() == preProcessing->getPreProcessingType() ){
70 
71  //Call the equals operator
72  *this = *(LowPassFilter*)preProcessing;
73 
74  return true;
75  }
76 
77  errorLog << "clone(const PreProcessing *preProcessing) - PreProcessing Types Do Not Match!" << endl;
78 
79  return false;
80 }
81 
82 bool LowPassFilter::process(const VectorDouble &inputVector){
83 
84  if( !initialized ){
85  errorLog << "process(const VectorDouble &inputVector) - Not initialized!" << endl;
86  return false;
87  }
88 
89  if( inputVector.size() != numInputDimensions ){
90  errorLog << "process(const VectorDouble &inputVector) - The size of the inputVector (" << inputVector.size() << ") does not match that of the filter (" << numInputDimensions << ")!" << endl;
91  return false;
92  }
93 
94  processedData = filter( inputVector );
95 
96  if( processedData.size() == numOutputDimensions ) return true;
97  return false;
98 
99 }
100 
102  if( initialized ) return init(filterFactor,gain,numInputDimensions);
103  return false;
104 }
105 
106 bool LowPassFilter::saveModelToFile(string filename) const{
107 
108  if( !initialized ){
109  errorLog << "saveModelToFile(string filename) - The HighPassFilter has not been initialized" << endl;
110  return false;
111  }
112 
113  std::fstream file;
114  file.open(filename.c_str(), std::ios::out);
115 
116  if( !saveModelToFile( file ) ){
117  file.close();
118  return false;
119  }
120 
121  file.close();
122 
123  return true;
124 }
125 
126 bool LowPassFilter::saveModelToFile(fstream &file) const{
127 
128  if( !file.is_open() ){
129  errorLog << "saveModelToFile(fstream &file) - The file is not open!" << endl;
130  return false;
131  }
132 
133  file << "GRT_LOW_PASS_FILTER_FILE_V1.0" << endl;
134 
135  file << "NumInputDimensions: " << numInputDimensions << endl;
136  file << "NumOutputDimensions: " << numOutputDimensions << endl;
137  file << "FilterFactor: " << filterFactor << endl;
138  file << "Gain: " << gain << endl;
139 
140  return true;
141 }
142 
143 bool LowPassFilter::loadModelFromFile(string filename){
144 
145  std::fstream file;
146  file.open(filename.c_str(), std::ios::in);
147 
148  if( !loadModelFromFile( file ) ){
149  file.close();
150  initialized = false;
151  return false;
152  }
153 
154  file.close();
155 
156  return true;
157 }
158 
160 
161  if( !file.is_open() ){
162  errorLog << "loadModelFromFile(fstream &file) - The file is not open!" << endl;
163  return false;
164  }
165 
166  string word;
167 
168  //Load the header
169  file >> word;
170 
171  if( word != "GRT_LOW_PASS_FILTER_FILE_V1.0" ){
172  errorLog << "loadModelFromFile(fstream &file) - Invalid file format!" << endl;
173  return false;
174  }
175 
176  //Load the number of input dimensions
177  file >> word;
178  if( word != "NumInputDimensions:" ){
179  errorLog << "loadModelFromFile(fstream &file) - Failed to read NumInputDimensions header!" << endl;
180  return false;
181  }
182  file >> numInputDimensions;
183 
184  //Load the number of output dimensions
185  file >> word;
186  if( word != "NumOutputDimensions:" ){
187  errorLog << "loadModelFromFile(fstream &file) - Failed to read NumOutputDimensions header!" << endl;
188  return false;
189  }
190  file >> numOutputDimensions;
191 
192  //Load the filter factor
193  file >> word;
194  if( word != "FilterFactor:" ){
195  errorLog << "loadModelFromFile(fstream &file) - Failed to read FilterFactor header!" << endl;
196  return false;
197  }
198  file >> filterFactor;
199 
200  //Load the number of output dimensions
201  file >> word;
202  if( word != "Gain:" ){
203  errorLog << "loadModelFromFile(fstream &file) - Failed to read Gain header!" << endl;
204  return false;
205  }
206  file >> gain;
207 
208  //Init the filter module to ensure everything is initialized correctly
209  return init(filterFactor,gain,numInputDimensions);
210 }
211 
212 bool LowPassFilter::init(double filterFactor,double gain,UINT numDimensions){
213 
214  initialized = false;
215 
216  if( numDimensions == 0 ){
217  errorLog << "init(double filterFactor,double gain,UINT numDimensions) - NumDimensions must be greater than 0!" << endl;
218  return false;
219  }
220 
221  if( filterFactor <= 0 ){
222  errorLog << "init(double filterFactor,double gain,UINT numDimensions) - FilterFactor must be greater than 0!" << endl;
223  return false;
224  }
225 
226  if( gain <= 0 ){
227  errorLog << "init(double filterFactor,double gain,UINT numDimensions) - Gain must be greater than 0!" << endl;
228  return false;
229  }
230 
231  this->filterFactor = filterFactor;
232  this->gain = gain;
233  this->numInputDimensions = numDimensions;
234  this->numOutputDimensions = numDimensions;
235  yy.clear();
236  yy.resize(numDimensions,0);
237  processedData.clear();
238  processedData.resize(numDimensions,0);
239  initialized = true;
240 
241  return true;
242 }
243 
244 double LowPassFilter::filter(double x){
245 
246  //If the filter has not been initialised then return 0, otherwise filter x and return y
247  if( !initialized ){
248  errorLog << "filter(double x) - The filter has not been initialized!" << endl;
249  return 0;
250  }
251 
252  VectorDouble y = filter(VectorDouble(1,x));
253 
254  if( y.size() == 0 ) return 0;
255  return y[0];
256 
257 }
258 
259 VectorDouble LowPassFilter::filter(const VectorDouble &x){
260 
261  if( !initialized ){
262  errorLog << "filter(const VectorDouble &x) - Not Initialized!" << endl;
263  return VectorDouble();
264  }
265 
266  if( x.size() != numInputDimensions ){
267  errorLog << "filter(const VectorDouble &x) - The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.size() << ")!" << endl;
268  return VectorDouble();
269  }
270 
271  for(UINT n=0; n<numInputDimensions; n++){
272  processedData[n] = (x[n] * filterFactor) + (yy[n] * (1.0 - filterFactor)) * gain;
273  yy[n] = processedData[n];
274  }
275  return processedData;
276 }
277 
278 bool LowPassFilter::setGain(double gain){
279  if( gain > 0 ){
280  this->gain = gain;
281  reset();
282  return true;
283  }
284  errorLog << "setGain(double gain) - Gain value must be greater than 0!" << endl;
285  return false;
286 }
287 
288 bool LowPassFilter::setFilterFactor(double filterFactor){
289  if( filterFactor > 0 ){
290  this->filterFactor = filterFactor;
291  reset();
292  return true;
293  }
294  errorLog << "setFilterFactor(double filterFactor) - FilterFactor value must be greater than 0!" << endl;
295  return false;
296 }
297 
298 bool LowPassFilter::setCutoffFrequency(double cutoffFrequency,double delta){
299  if( cutoffFrequency > 0 && delta > 0 ){
300  double RC = (1.0/TWO_PI) /cutoffFrequency;
301  filterFactor = delta / (RC+delta);
302  reset();
303  return true;
304  }
305  return false;
306 }
307 
308 
309 }//End of namespace GRT
bool setFilterFactor(double filterFactor)
Definition: AdaBoost.cpp:25
LowPassFilter & operator=(const LowPassFilter &rhs)
bool setCutoffFrequency(double cutoffFrequency, double delta)
virtual bool process(const VectorDouble &inputVector)
virtual bool reset()
bool setGain(double gain)
double filterFactor
The filter factor (alpha) of the filter.
string getPreProcessingType() const
LowPassFilter(double filterFactor=0.1, double gain=1, UINT numDimensions=1, double cutoffFrequency=-1, double delta=-1)
virtual ~LowPassFilter()
virtual bool saveModelToFile(string filename) const
The class implements a low pass filter.
bool copyBaseVariables(const PreProcessing *preProcessingModule)
VectorDouble yy
The previous output value(s)
double gain
The gain factor of the filter.
virtual bool loadModelFromFile(string filename)
virtual bool deepCopyFrom(const PreProcessing *preProcessing)
double filter(const double x)