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.
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 #define GRT_DLL_EXPORTS
22 #include "TimeseriesBuffer.h"
23 
24 GRT_BEGIN_NAMESPACE
25 
26 //Register the TimeseriesBuffer module with the FeatureExtraction base class
27 RegisterFeatureExtractionModule< TimeseriesBuffer > TimeseriesBuffer::registerModule("TimeseriesBuffer");
28 
29 TimeseriesBuffer::TimeseriesBuffer(UINT bufferSize,UINT numDimensions){
30 
31  classType = "TimeseriesBuffer";
32  featureExtractionType = classType;
33  debugLog.setProceedingText("[DEBUG TimeseriesBuffer]");
34  errorLog.setProceedingText("[ERROR TimeseriesBuffer]");
35  warningLog.setProceedingText("[WARNING TimeseriesBuffer]");
36 
37  init(bufferSize,numDimensions);
38 }
39 
41 
42  classType = "TimeseriesBuffer";
43  featureExtractionType = classType;
44  debugLog.setProceedingText("[DEBUG TimeseriesBuffer]");
45  errorLog.setProceedingText("[ERROR TimeseriesBuffer]");
46  warningLog.setProceedingText("[WARNING TimeseriesBuffer]");
47 
48  //Invoke the equals operator to copy the data from the rhs instance to this instance
49  *this = rhs;
50 }
51 
53 
54 }
55 
57  if(this!=&rhs){
58  this->bufferSize = rhs.bufferSize;
59  this->dataBuffer = rhs.dataBuffer;
60 
62  }
63  return *this;
64 }
65 
66 bool TimeseriesBuffer::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 = *(TimeseriesBuffer*)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.size() != numInputDimensions ){
91  errorLog << "computeFeatures(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.size() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
92  return false;
93  }
94 
95  update( inputVector );
96 
97  return true;
98 }
99 
101  if( initialized ){
102  return init( bufferSize, numInputDimensions );
103  }
104  return false;
105 }
106 
107 bool TimeseriesBuffer::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 TimeseriesBuffer::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 TimeseriesBuffer::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_TIMESERIES_BUFFER_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 zero crossing counter settings
153  file << "BufferSize: " << dataBuffer.getSize() << std::endl;
154 
155  return true;
156 }
157 
158 bool TimeseriesBuffer::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_TIMESERIES_BUFFER_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  file >> word;
181  if( word != "BufferSize:" ){
182  errorLog << "loadModelFromFile(fstream &file) - Failed to read BufferSize header!" << std::endl;
183  return false;
184  }
185  file >> bufferSize;
186 
187  //Init the TimeseriesBuffer module to ensure everything is initialized correctly
188  return init(bufferSize,numInputDimensions);
189 }
190 
191 bool TimeseriesBuffer::init(UINT bufferSize,UINT numDimensions){
192 
193  initialized = false;
194  featureDataReady = false;
195 
196  if( bufferSize == 0 ){
197  errorLog << "init(UINT bufferSize,UINT numDimensions) - The bufferSize must be greater than zero!" << std::endl;
198  return false;
199  }
200 
201  if( numDimensions == 0 ){
202  errorLog << "init(UINT bufferSize,UINT numDimensions) - The numDimensions must be greater than zero!" << std::endl;
203  return false;
204  }
205 
206  //Setup the databuffer
207  numInputDimensions = numDimensions;
208  numOutputDimensions = bufferSize * numInputDimensions;
209  this->bufferSize = bufferSize;
210  dataBuffer.resize( bufferSize, VectorFloat(numInputDimensions,0) );
211  featureVector.resize(numOutputDimensions,0);
212 
213  //Flag that the timeseries buffer has been initialized
214  initialized = true;
215 
216  return true;
217 }
218 
219 
221  return update(VectorFloat(1,x));
222 }
223 
225 
226  if( !initialized ){
227  errorLog << "update(const VectorFloat &x) - Not Initialized!" << std::endl;
228  return VectorFloat();
229  }
230 
231  if( x.getSize() != numInputDimensions ){
232  errorLog << "update(const VectorFloat &x)- The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.getSize() << ")!" << std::endl;
233  return VectorFloat();
234  }
235 
236  //Add the new data to the buffer
237  dataBuffer.push_back( x );
238 
239  //Search the buffer for the zero crossing features
240  UINT colIndex = 0;
241  for(UINT j=0; j<numInputDimensions; j++){
242  for(UINT i=0; i<dataBuffer.getSize(); i++){
243  featureVector[ colIndex++ ] = dataBuffer[i][j];
244  }
245  }
246 
247  //Flag that the feature data has been computed
248  if( dataBuffer.getBufferFilled() ){
249  featureDataReady = true;
250  }else featureDataReady = false;
251 
252  return featureVector;
253 }
254 
255 bool TimeseriesBuffer::setBufferSize(UINT bufferSize){
256  if( bufferSize > 0 ){
257  this->bufferSize = bufferSize;
258  if( initialized ) return init(bufferSize, numInputDimensions);
259  return true;
260  }
261  errorLog << "setBufferSize(UINT bufferSize) - The bufferSize must be larger than zero!" << std::endl;
262  return false;
263 }
264 
266  if( initialized ) return bufferSize;
267  return 0;
268 }
269 
271  if( initialized ) return dataBuffer.getData();
272  return Vector< VectorFloat >();
273 }
274 
275 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
UINT getSize() const
Definition: Vector.h:191
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)