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.
MovementIndex.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 "MovementIndex.h"
23 
24 GRT_BEGIN_NAMESPACE
25 
26 //Define the string that will be used to identify the object
27 std::string MovementIndex::id = "MovementIndex";
28 std::string MovementIndex::getId() { return MovementIndex::id; }
29 
30 //Register the MovementIndex module with the FeatureExtraction base class
32 
33 MovementIndex::MovementIndex(const UINT bufferLength,const UINT numDimensions) : FeatureExtraction( MovementIndex::getId() )
34 {
35  init(bufferLength,numDimensions);
36 }
37 
39 {
40  //Invoke the equals operator to copy the data from the rhs instance to this instance
41  *this = rhs;
42 }
43 
45 
46 }
47 
49  if(this!=&rhs){
50  this->bufferLength = rhs.bufferLength;
51  this->dataBuffer = rhs.dataBuffer;
52 
53  //Copy the base variables
55  }
56  return *this;
57 }
58 
59 bool MovementIndex::deepCopyFrom(const FeatureExtraction *featureExtraction){
60 
61  if( featureExtraction == NULL ) return false;
62 
63  if( this->getId() == featureExtraction->getId() ){
64 
65  //Invoke the equals operator to copy the data from the rhs instance to this instance
66  *this = *dynamic_cast<const MovementIndex*>(featureExtraction);
67 
68  return true;
69  }
70 
71  errorLog << "deepCopyFrom(FeatureExtraction *featureExtraction) - FeatureExtraction Types Do Not Match!" << std::endl;
72 
73  return false;
74 }
75 
77 
78  if( !initialized ){
79  errorLog << "computeFeatures(const VectorFloat &inputVector) - Not initialized!" << std::endl;
80  return false;
81  }
82 
83  if( inputVector.getSize() != numInputDimensions ){
84  errorLog << "computeFeatures(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.getSize() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
85  return false;
86  }
87 
88  featureVector = update( inputVector );
89 
90  return true;
91 }
92 
94  if( initialized ){
95  return init(bufferLength,numInputDimensions);
96  }
97  return false;
98 }
99 
100 bool MovementIndex::save( std::fstream &file ) const{
101 
102  if( !file.is_open() ){
103  errorLog << "save(fstream &file) - The file is not open!" << std::endl;
104  return false;
105  }
106 
107  //Write the file header
108  file << "GRT_MOVEMENT_INDEX_FILE_V1.0" << std::endl;
109 
110  //Save the base settings to the file
112  errorLog << "save(fstream &file) - Failed to save base feature extraction settings to file!" << std::endl;
113  return false;
114  }
115 
116  //Write the movement index settings to the file
117  file << "BufferLength: " << bufferLength << std::endl;
118 
119  return true;
120 }
121 
122 bool MovementIndex::load( std::fstream &file ){
123 
124  if( !file.is_open() ){
125  errorLog << "load(fstream &file) - The file is not open!" << std::endl;
126  return false;
127  }
128 
129  std::string word;
130 
131  //Load the header
132  file >> word;
133 
134  if( word != "GRT_MOVEMENT_INDEX_FILE_V1.0" ){
135  errorLog << "load(fstream &file) - Invalid file format!" << std::endl;
136  return false;
137  }
138 
140  errorLog << "load(fstream &file) - Failed to load base feature extraction settings from file!" << std::endl;
141  return false;
142  }
143 
144  //Load the BufferLength
145  file >> word;
146  if( word != "BufferLength:" ){
147  errorLog << "load(fstream &file) - Failed to read BufferLength header!" << std::endl;
148  return false;
149  }
150  file >> bufferLength;
151 
152  //Init the MovementIndex module to ensure everything is initialized correctly
153  return init(bufferLength,numInputDimensions);
154 }
155 
156 bool MovementIndex::init(const UINT bufferLength,const UINT numDimensions){
157 
158  initialized = false;
159 
160  if( bufferLength == 0 ){
161  errorLog << "init(...) - The number of bufferLength must be greater than zero!" << std::endl;
162  return false;
163  }
164 
165  if( numDimensions == 0 ){
166  errorLog << "init(...) - The number of dimensions must be greater than zero!" << std::endl;
167  return false;
168  }
169 
170  this->bufferLength = bufferLength;
171  this->numInputDimensions = numDimensions;
172  this->numOutputDimensions = numInputDimensions;
173  featureDataReady = false;
174 
175  //Resize the feature vector
176  featureVector.resize(numInputDimensions);
177 
178  //Resize the raw trajectory data buffer
179  dataBuffer.resize( bufferLength, VectorFloat(numInputDimensions,0) );
180 
181  //Flag that the zero crossing counter has been initialized
182  initialized = true;
183 
184  return true;
185 }
186 
187 
189  return update(VectorFloat(1,x));
190 }
191 
193 
194  #ifdef GRT_SAFE_CHECKING
195  if( !initialized ){
196  errorLog << "update(const VectorFloat &x) - Not Initialized!" << std::endl;
197  return VectorFloat();
198  }
199 
200  if( x.getSize() != numInputDimensions ){
201  errorLog << "update(const VectorFloat &x)- The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.getSize() << ")!" << std::endl;
202  return VectorFloat();
203  }
204  #endif
205 
206  //Add the new data to the trajectory data buffer
207  dataBuffer.push_back( x );
208 
209  //Only flag that the feature data is ready if the trajectory data is full
210  if( !dataBuffer.getBufferFilled() ){
211  featureDataReady = false;
212  for(UINT i=0; i<featureVector.getSize(); i++){
213  featureVector[i] = 0;
214  }
215  return featureVector;
216  }else featureDataReady = true;
217 
218  //Compute the movement index (which is the RMS error)
219  VectorFloat mu(numInputDimensions,0);
220 
221  //Compute mu
222  for(UINT j=0; j<numInputDimensions; j++){
223  for(UINT i=0; i<dataBuffer.getSize(); i++){
224  mu[j] += dataBuffer[i][j];
225  }
226  mu[j] /= Float(dataBuffer.getSize());
227  }
228 
229  for(UINT j=0; j<numInputDimensions; j++){
230  featureVector[j] = 0;
231  for(UINT i=0; i<dataBuffer.getSize(); i++){
232  featureVector[j] += grt_sqr( dataBuffer[i][j] - mu[j] );
233  }
234  featureVector[j] = grt_sqrt( featureVector[j]/Float(dataBuffer.getSize()) );
235  }
236 
237  return featureVector;
238 }
239 
241  if( initialized ){
242  return dataBuffer;
243  }
245 }
246 
247 GRT_END_NAMESPACE
bool push_back(const T &value)
std::string getId() const
Definition: GRTBase.cpp:85
virtual ~MovementIndex()
VectorFloat update(const Float x)
bool saveFeatureExtractionSettingsToFile(std::fstream &file) const
bool getBufferFilled() const
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
CircularBuffer< VectorFloat > getData() const
MovementIndex(const UINT bufferLength=100, const UINT numDimensions=1)
UINT getSize() const
Definition: Vector.h:201
virtual bool deepCopyFrom(const FeatureExtraction *featureExtraction)
virtual bool save(std::fstream &file) const
static std::string getId()
virtual bool reset()
bool loadFeatureExtractionSettingsFromFile(std::fstream &file)
MovementIndex & operator=(const MovementIndex &rhs)
This class implements the MovementIndex feature module. The MovementIndex module computes the amount ...
virtual bool computeFeatures(const VectorFloat &inputVector)
bool copyBaseVariables(const FeatureExtraction *featureExtractionModule)
virtual bool load(std::fstream &file)
unsigned int getSize() const
bool resize(const unsigned int newBufferSize)