GestureRecognitionToolkit  Version: 0.2.5
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
Derivative.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 "Derivative.h"
23 
24 GRT_BEGIN_NAMESPACE
25 
26 //Define the string that will be used to identify the object
27 const std::string Derivative::id = "Derivative";
28 std::string Derivative::getId() { return Derivative::id; }
29 
30 //Register the Derivative module with the PreProcessing base class
31 RegisterPreProcessingModule< Derivative > Derivative::registerModule( Derivative::getId() );
32 
33 Derivative::Derivative(const UINT derivativeOrder,const Float delta,const UINT numDimensions,const bool filterData,const UINT filterSize) : PreProcessing( Derivative::getId() )
34 {
35  init(derivativeOrder,delta,numDimensions,filterData,filterSize);
36 }
37 
39 {
40 
41  this->derivativeOrder = rhs.derivativeOrder;
42  this->filterSize = rhs.filterSize;
43  this->delta = rhs.delta;
44  this->filterData = rhs.filterData;
45  this->filter = rhs.filter;
46  this->yy = rhs.yy;
47  this->yyy = rhs.yyy;
48 
50 }
51 
53 
54 }
55 
57  if( this != &rhs ){
58  this->derivativeOrder = rhs.derivativeOrder;
59  this->filterSize = rhs.filterSize;
60  this->delta = rhs.delta;
61  this->filterData = rhs.filterData;
62  this->filter = rhs.filter;
63  this->yy = rhs.yy;
64  this->yyy = rhs.yyy;
66  }
67  return *this;
68 }
69 
70 bool Derivative::deepCopyFrom(const PreProcessing *preProcessing){
71 
72  if( preProcessing == NULL ) return false;
73 
74  if( this->getId() == preProcessing->getId() ){
75 
76  const Derivative *ptr = dynamic_cast<const Derivative*>(preProcessing);
77 
78  //Clone the Derivative values
79  this->derivativeOrder = ptr->derivativeOrder;
80  this->filterSize = ptr->filterSize;
81  this->delta = ptr->delta;
82  this->filterData = ptr->filterData;
83  this->filter = ptr->filter;
84  this->yy = ptr->yy;
85  this->yyy = ptr->yyy;
86 
87  //Clone the base class variables
88  return copyBaseVariables( preProcessing );
89  }
90 
91  errorLog << "deepCopyFrom(const PreProcessing *preProcessing) - PreProcessing Types Do Not Match!" << std::endl;
92 
93  return false;
94 }
95 
96 bool Derivative::process(const VectorFloat &inputVector){
97 
98  if( !initialized ){
99  errorLog << "process(const VectorFloat &inputVector) - Not initialized!" << std::endl;
100  return false;
101  }
102 
103  if( inputVector.getSize() != numInputDimensions ){
104  errorLog << "process(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.size() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
105  return false;
106  }
107 
108  computeDerivative( inputVector );
109 
110  if( processedData.size() == numOutputDimensions ) return true;
111  return false;
112 }
113 
115  if( initialized ) return init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
116  return false;
117 }
118 
119 bool Derivative::save(std::fstream &file) const{
120 
121  if( !file.is_open() ){
122  errorLog << "save(fstream &file) - The file is not open!" << std::endl;
123  return false;
124  }
125 
126  file << "GRT_DERIVATIVE_FILE_V1.0" << std::endl;
127 
128  file << "NumInputDimensions: " << numInputDimensions << std::endl;
129  file << "NumOutputDimensions: " << numOutputDimensions << std::endl;
130  file << "DerivativeOrder: " << derivativeOrder << std::endl;
131  file << "FilterSize: " << filterSize << std::endl;
132  file << "Delta: " << delta << std::endl;
133  file << "FilterData: " << filterData << std::endl;
134 
135  return true;
136 }
137 
138 bool Derivative::load(std::fstream &file){
139 
140  if( !file.is_open() ){
141  errorLog << "load(fstream &file) - The file is not open!" << std::endl;
142  return false;
143  }
144 
145  std::string word;
146 
147  //Load the header
148  file >> word;
149 
150  if( word != "GRT_DERIVATIVE_FILE_V1.0" ){
151  errorLog << "load(fstream &file) - Invalid file format!" << std::endl;
152  return false;
153  }
154 
155  //Load the number of input dimensions
156  file >> word;
157  if( word != "NumInputDimensions:" ){
158  errorLog << "load(fstream &file) - Failed to read NumInputDimensions header!" << std::endl;
159  return false;
160  }
161  file >> numInputDimensions;
162 
163  //Load the number of output dimensions
164  file >> word;
165  if( word != "NumOutputDimensions:" ){
166  errorLog << "load(fstream &file) - Failed to read NumOutputDimensions header!" << std::endl;
167  return false;
168  }
169  file >> numOutputDimensions;
170 
171  //Load the DerivativeOrder
172  file >> word;
173  if( word != "DerivativeOrder:" ){
174  errorLog << "load(fstream &file) - Failed to read DerivativeOrder header!" << std::endl;
175  return false;
176  }
177  file >> derivativeOrder;
178 
179  //Load the FilterSize
180  file >> word;
181  if( word != "FilterSize:" ){
182  errorLog << "load(fstream &file) - Failed to read FilterSize header!" << std::endl;
183  return false;
184  }
185  file >> filterSize;
186 
187  //Load the Delta
188  file >> word;
189  if( word != "Delta:" ){
190  errorLog << "load(fstream &file) - Failed to read Delta header!" << std::endl;
191  return false;
192  }
193  file >> delta;
194 
195  //Load if the data should be filtered
196  file >> word;
197  if( word != "FilterData:" ){
198  errorLog << "load(fstream &file) - Failed to read FilterData header!" << std::endl;
199  return false;
200  }
201  file >> filterData;
202 
203  //Init the derivative module to ensure everything is initialized correctly
204  return init(derivativeOrder,delta,numInputDimensions,filterData,filterSize);
205 }
206 
207 bool Derivative::init(const UINT derivativeOrder,const Float delta,const UINT numDimensions,const bool filterData,const UINT filterSize){
208 
209  initialized = false;
210 
211  if( derivativeOrder != FIRST_DERIVATIVE && derivativeOrder != SECOND_DERIVATIVE ){
212  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - Unknown derivativeOrder!" << std::endl;
213  return false;
214  }
215 
216  if( numDimensions == 0 ){
217  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - NumDimensions must be greater than 0!" << std::endl;
218  return false;
219  }
220 
221  if( delta <= 0 ){
222  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - Delta must be greater than 0!" << std::endl;
223  return false;
224  }
225 
226  if( filterSize == 0 ){
227  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - FilterSize must be greater than zero!" << std::endl;
228  return false;
229  }
230 
231  this->derivativeOrder = derivativeOrder;
232  this->delta = delta;
233  this->numInputDimensions = numDimensions;
234  this->numOutputDimensions = numDimensions;
235  this->filterData = filterData;
236  this->filterSize = filterSize;
237  filter.init(filterSize, numDimensions);
238  yy.clear();
239  yy.resize(numDimensions,0);
240  yyy.clear();
241  yyy.resize(numDimensions,0);
242  processedData.clear();
243  processedData.resize(numDimensions,0);
244  initialized = true;
245  return true;
246 }
247 
248 Float Derivative::computeDerivative(const Float x){
249 
250  if( numInputDimensions != 1 ){
251  errorLog << "computeDerivative(const Float x) - The Number Of Input Dimensions is not 1! NumInputDimensions: " << numInputDimensions << std::endl;
252  return 0;
253  }
254 
256 
257  if( y.size() == 0 ) return 0 ;
258 
259  return y[0];
260 }
261 
263 
264  if( !initialized ){
265  errorLog << "computeDerivative(const VectorFloat &x) - Not Initialized!" << std::endl;
266  return VectorFloat();
267  }
268 
269  if( x.size() != numInputDimensions ){
270  errorLog << "computeDerivative(const VectorFloat &x) - The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.size() << ")!" << std::endl;
271  return VectorFloat();
272  }
273 
274  VectorFloat y;
275  if( filterData ){
276  y = filter.filter( x );
277  }else y = x;
278 
279  for(UINT n=0; n<numInputDimensions; n++){
280  processedData[n] = (y[n]-yy[n])/delta;
281  yy[n] = y[n];
282  }
283 
284  if( derivativeOrder == SECOND_DERIVATIVE ){
285  Float tmp = 0;
286  for(UINT n=0; n<numInputDimensions; n++){
287  tmp = processedData[n];
288  processedData[n] = (processedData[n]-yyy[n])/delta;
289  yyy[n] = tmp;
290  }
291  }
292 
293  return processedData;
294 }
295 
297  if( derivativeOrder == FIRST_DERIVATIVE || derivativeOrder == SECOND_DERIVATIVE ){
298  this->derivativeOrder = derivativeOrder;
299  if( initialized ) init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
300  return true;
301  }
302  errorLog << "setDerivativeOrder(UINT derivativeOrder) - Unkown derivativeOrder" << std::endl;
303  return false;
304 }
305 
307  if( filterSize > 0 ){
308  this->filterSize = filterSize;
309  if( initialized ) init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
310  return true;
311  }
312  errorLog << "setFilterSize(UINT filterSize) - FilterSize must be greater than zero!" << std::endl;
313  return false;
314 }
315 
317  this->filterData = filterData;
318  if( initialized ) init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
319  return true;
320 }
321 
323  if( initialized ){ return filterSize; }
324  return 0;
325 }
326 
328 
329  switch( derivativeOrder ){
330  case 0:
331  return processedData[0];
332  break;
333  case( FIRST_DERIVATIVE ):
334  return yy[0];
335  break;
336  case( SECOND_DERIVATIVE ):
337  return yyy[0];
338  break;
339  default:
340  warningLog << "getDerivative(UINT derivativeOrder) - Unkown derivativeOrder: " << derivativeOrder << std::endl;
341  break;
342  }
343 
344  return 0;
345 }
346 
348 
349  switch( derivativeOrder ){
350  case 0:
351  return processedData;
352  break;
353  case( FIRST_DERIVATIVE ):
354  return yy;
355  break;
356  case( SECOND_DERIVATIVE ):
357  return yyy;
358  break;
359  default:
360  warningLog << "getDerivative(UINT derivativeOrder) - Unkown derivativeOrder: " << derivativeOrder << std::endl;
361  break;
362  }
363 
364  return VectorFloat();
365 }
366 
367 GRT_END_NAMESPACE
std::string getId() const
Definition: GRTBase.cpp:85
virtual bool save(std::fstream &file) const
Definition: Derivative.cpp:119
UINT getFilterSize() const
Definition: Derivative.cpp:322
UINT filterSize
The size of the filter used to filter the input data before the derivative is computed.
Definition: Derivative.h:232
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
VectorFloat yy
A buffer holding the previous input value(s)
Definition: Derivative.h:236
bool setDerivativeOrder(const UINT derivativeOrder)
Definition: Derivative.cpp:296
UINT getSize() const
Definition: Vector.h:201
bool init(const UINT filterSize, const UINT numDimensions)
bool enableFiltering(const bool filterData)
Definition: Derivative.cpp:316
VectorFloat yyy
A buffer holding the previous first derivative values.
Definition: Derivative.h:237
Float computeDerivative(const Float x)
Definition: Derivative.cpp:248
virtual bool load(std::fstream &file)
Definition: Derivative.cpp:138
bool setFilterSize(const UINT filterSize)
Definition: Derivative.cpp:306
virtual bool reset()
Definition: Derivative.cpp:114
Derivative & operator=(const Derivative &rhs)
Definition: Derivative.cpp:56
Float filter(const Float x)
static std::string getId()
Definition: Derivative.cpp:28
Derivative(const UINT derivativeOrder=FIRST_DERIVATIVE, const Float delta=1, const UINT numDimensions=1, const bool filterData=true, const UINT filterSize=3)
Definition: Derivative.cpp:33
virtual bool process(const VectorFloat &inputVector)
Definition: Derivative.cpp:96
bool filterData
Flags if the input data should be filtered before the derivative is computed.
Definition: Derivative.h:234
The Derivative class computes either the first or second order derivative of the input signal...
Definition: Derivative.h:39
Float delta
The estimated time between sensor samples.
Definition: Derivative.h:233
bool copyBaseVariables(const PreProcessing *preProcessingModule)
virtual ~Derivative()
Definition: Derivative.cpp:52
UINT derivativeOrder
The order of the derivative that will be computed (either FIRST_DERIVATIVE or SECOND_DERIVATIVE) ...
Definition: Derivative.h:231
virtual bool deepCopyFrom(const PreProcessing *preProcessing)
Definition: Derivative.cpp:70
Float getDerivative(const UINT derivativeOrder=FIRST_DERIVATIVE) const
Definition: Derivative.cpp:327
VectorFloat getDerivatives(const UINT derivativeOrder=FIRST_DERIVATIVE) const
Definition: Derivative.cpp:347
MovingAverageFilter filter
The filter used to low pass filter the input data.
Definition: Derivative.h:235