GestureRecognitionToolkit  Version: 0.1.0
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
MovingAverageFilter.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 "MovingAverageFilter.h"
22 
23 GRT_BEGIN_NAMESPACE
24 
25 //Register the MovingAverageFilter module with the PreProcessing base class
26 RegisterPreProcessingModule< MovingAverageFilter > MovingAverageFilter::registerModule("MovingAverageFilter");
27 
28 MovingAverageFilter::MovingAverageFilter(UINT filterSize,UINT numDimensions){
29 
30  classType = "MovingAverageFilter";
31  preProcessingType = classType;
32  debugLog.setProceedingText("[DEBUG MovingAverageFilter]");
33  errorLog.setProceedingText("[ERROR MovingAverageFilter]");
34  warningLog.setProceedingText("[WARNING MovingAverageFilter]");
35  init(filterSize,numDimensions);
36 }
37 
39 
40  classType = "MovingAverageFilter";
41  preProcessingType = classType;
42  debugLog.setProceedingText("[DEBUG MovingAverageFilter]");
43  errorLog.setProceedingText("[ERROR MovingAverageFilter]");
44  warningLog.setProceedingText("[WARNING MovingAverageFilter]");
45 
46  //Zero this instance
47  this->filterSize = 0;
48  this->inputSampleCounter = 0;
49 
50  //Copy the settings from the rhs instance
51  *this = rhs;
52 }
53 
55 
56 }
57 
59  if(this!=&rhs){
60  //Clear this instance
61  this->filterSize = 0;
62  this->inputSampleCounter = 0;
63  this->dataBuffer.clear();
64 
65  //Copy from the rhs instance
66  if( rhs.initialized ){
67  this->init( rhs.filterSize, rhs.numInputDimensions );
68  this->dataBuffer = rhs.dataBuffer;
69  }
70 
71  //Copy the preprocessing base variables
73  }
74  return *this;
75 }
76 
78 
79  if( preProcessing == NULL ) return false;
80 
81  if( this->getPreProcessingType() == preProcessing->getPreProcessingType() ){
82 
83  //Call the equals operator
84  *this = *(MovingAverageFilter*)preProcessing;
85 
86  return true;
87  }
88 
89  errorLog << "clone(const PreProcessing *preProcessing) - PreProcessing Types Do Not Match!" << std::endl;
90 
91  return false;
92 }
93 
94 
95 bool MovingAverageFilter::process(const VectorFloat &inputVector){
96 
97  if( !initialized ){
98  errorLog << "process(const VectorFloat &inputVector) - The filter has not been initialized!" << std::endl;
99  return false;
100  }
101 
102  if( inputVector.getSize() != numInputDimensions ){
103  errorLog << "process(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.getSize() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
104  return false;
105  }
106 
107  filter( inputVector );
108 
109  if( processedData.getSize() == numOutputDimensions ) return true;
110 
111  return false;
112 }
113 
115  if( initialized ) return init(filterSize,numInputDimensions);
116  return false;
117 }
118 
119 bool MovingAverageFilter::saveModelToFile(std::string filename) const{
120 
121  if( !initialized ){
122  errorLog << "saveModelToFile(string filename) - The MovingAverageFilter has not been initialized" << std::endl;
123  return false;
124  }
125 
126  std::fstream file;
127  file.open(filename.c_str(), std::ios::out);
128 
129  if( !saveModelToFile( file ) ){
130  file.close();
131  return false;
132  }
133 
134  file.close();
135 
136  return true;
137 }
138 
139 bool MovingAverageFilter::saveModelToFile(std::fstream &file) const{
140 
141  if( !file.is_open() ){
142  errorLog << "saveModelToFile(fstream &file) - The file is not open!" << std::endl;
143  return false;
144  }
145 
146  file << "GRT_MOVING_AVERAGE_FILTER_FILE_V1.0" << std::endl;
147 
148  file << "NumInputDimensions: " << numInputDimensions << std::endl;
149  file << "NumOutputDimensions: " << numOutputDimensions << std::endl;
150  file << "FilterSize: " << filterSize << std::endl;
151 
152  return true;
153 }
154 
155 bool MovingAverageFilter::loadModelFromFile(std::string filename){
156 
157  std::fstream file;
158  file.open(filename.c_str(), std::ios::in);
159 
160  if( !loadModelFromFile( file ) ){
161  file.close();
162  initialized = false;
163  return false;
164  }
165 
166  file.close();
167 
168  return true;
169 }
170 
171 bool MovingAverageFilter::loadModelFromFile(std::fstream &file){
172 
173  if( !file.is_open() ){
174  errorLog << "loadModelFromFile(fstream &file) - The file is not open!" << std::endl;
175  return false;
176  }
177 
178  std::string word;
179 
180  //Load the header
181  file >> word;
182 
183  if( word != "GRT_MOVING_AVERAGE_FILTER_FILE_V1.0" ){
184  errorLog << "loadModelFromFile(fstream &file) - Invalid file format!" << std::endl;
185  return false;
186  }
187 
188  //Load the number of input dimensions
189  file >> word;
190  if( word != "NumInputDimensions:" ){
191  errorLog << "loadModelFromFile(fstream &file) - Failed to read NumInputDimensions header!" << std::endl;
192  return false;
193  }
194  file >> numInputDimensions;
195 
196  //Load the number of output dimensions
197  file >> word;
198  if( word != "NumOutputDimensions:" ){
199  errorLog << "loadModelFromFile(fstream &file) - Failed to read NumOutputDimensions header!" << std::endl;
200  return false;
201  }
202  file >> numOutputDimensions;
203 
204  //Load the filter factor
205  file >> word;
206  if( word != "FilterSize:" ){
207  errorLog << "loadModelFromFile(fstream &file) - Failed to read FilterSize header!" << std::endl;
208  return false;
209  }
210  file >> filterSize;
211 
212  //Init the filter module to ensure everything is initialized correctly
213  return init(filterSize,numInputDimensions);
214 }
215 
216 bool MovingAverageFilter::init(UINT filterSize,UINT numDimensions){
217 
218  //Cleanup the old memory
219  initialized = false;
220  inputSampleCounter = 0;
221 
222  if( filterSize == 0 ){
223  errorLog << "init(UINT filterSize,UINT numDimensions) - Filter size can not be zero!" << std::endl;
224  return false;
225  }
226 
227  if( numDimensions == 0 ){
228  errorLog << "init(UINT filterSize,UINT numDimensions) - The number of dimensions must be greater than zero!" << std::endl;
229  return false;
230  }
231 
232  //Resize the filter
233  this->filterSize = filterSize;
234  this->numInputDimensions = numDimensions;
235  this->numOutputDimensions = numDimensions;
236  processedData.clear();
237  processedData.resize(numDimensions,0);
238  initialized = dataBuffer.resize( filterSize, VectorFloat(numInputDimensions,0) );
239 
240  if( !initialized ){
241  errorLog << "init(UINT filterSize,UINT numDimensions) - Failed to resize dataBuffer!" << std::endl;
242  }
243 
244  return initialized;
245 }
246 
247 Float MovingAverageFilter::filter(const Float x){
248 
249  //If the filter has not been initialised then return 0, otherwise filter x and return y
250  if( !initialized ){
251  errorLog << "filter(const Float x) - The filter has not been initialized!" << std::endl;
252  return 0;
253  }
254 
255  VectorFloat y = filter(VectorFloat(1,x));
256 
257  if( y.size() == 0 ) return 0;
258  return y[0];
259 }
260 
262 
263  //If the filter has not been initialised then return 0, otherwise filter x and return y
264  if( !initialized ){
265  errorLog << "filter(const VectorFloat &x) - The filter has not been initialized!" << std::endl;
266  return VectorFloat();
267  }
268 
269  if( x.size() != numInputDimensions ){
270  errorLog << "filter(const VectorFloat &x) - The size of the input vector (" << x.getSize() << ") does not match that of the number of dimensions of the filter (" << numInputDimensions << ")!" << std::endl;
271  return VectorFloat();
272  }
273 
275 
276  //Add the new value to the buffer
277  dataBuffer.push_back( x );
278 
279  for(unsigned int j=0; j<numInputDimensions; j++){
280  processedData[j] = 0;
281  for(unsigned int i=0; i<inputSampleCounter; i++) {
282  processedData[j] += dataBuffer[i][j];
283  }
284  processedData[j] /= Float(inputSampleCounter);
285  }
286 
287  return processedData;
288 }
289 
290 GRT_END_NAMESPACE
virtual bool process(const VectorFloat &inputVector)
bool push_back(const T &value)
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
The MovingAverageFilter implements a low pass moving average filter.
CircularBuffer< VectorFloat > dataBuffer
A buffer to store the previous N values, N = filterSize.
virtual bool deepCopyFrom(const PreProcessing *preProcessing)
virtual bool loadModelFromFile(std::string filename)
unsigned int getSize() const
Definition: Vector.h:193
Float filter(const Float x)
virtual bool saveModelToFile(std::string filename) const
std::string getPreProcessingType() const
UINT filterSize
The size of the filter.
MovingAverageFilter(UINT filterSize=5, UINT numDimensions=1)
MovingAverageFilter & operator=(const MovingAverageFilter &rhs)
bool copyBaseVariables(const PreProcessing *preProcessingModule)
UINT inputSampleCounter
A counter to keep track of the number of input samples.
bool resize(const unsigned int newBufferSize)