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