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