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