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.
ClassLabelChangeFilter.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 "ClassLabelChangeFilter.h"
22 
23 GRT_BEGIN_NAMESPACE
24 
25 //Register the ClassLabelChangeFilter module with the PostProcessing base class
26 RegisterPostProcessingModule< ClassLabelChangeFilter > ClassLabelChangeFilter::registerModule("ClassLabelChangeFilter");
27 
29 
30  classType = "ClassLabelChangeFilter";
31  postProcessingType = classType;
32  postProcessingInputMode = INPUT_MODE_PREDICTED_CLASS_LABEL;
33  postProcessingOutputMode = OUTPUT_MODE_PREDICTED_CLASS_LABEL;
34  debugLog.setProceedingText("[DEBUG ClassLabelChangeFilter]");
35  errorLog.setProceedingText("[ERROR ClassLabelChangeFilter]");
36  warningLog.setProceedingText("[WARNING ClassLabelChangeFilter]");
37  init();
38 }
39 
41 
42  classType = "ClassLabelChangeFilter";
43  postProcessingType = classType;
44  postProcessingInputMode = INPUT_MODE_PREDICTED_CLASS_LABEL;
45  postProcessingOutputMode = OUTPUT_MODE_PREDICTED_CLASS_LABEL;
46  debugLog.setProceedingText("[DEBUG ClassLabelChangeFilter]");
47  errorLog.setProceedingText("[ERROR ClassLabelChangeFilter]");
48  warningLog.setProceedingText("[WARNING ClassLabelChangeFilter]");
49 
50  //Copy the ClassLabelChangeFilter values
51  this->filteredClassLabel = rhs.filteredClassLabel;
52  this->labelChanged = rhs.labelChanged;
53 
54  //Clone the post processing base variables
56 }
57 
59 
60 }
61 
63 
64  if( this != &rhs ){
65  //Copy the ClassLabelChangeFilter values
66  this->filteredClassLabel = rhs.filteredClassLabel;
67  this->labelChanged = rhs.labelChanged;
68 
69  //Clone the post processing base variables
71  }
72  return *this;
73 }
74 
76 
77  if( postProcessing == NULL ) return false;
78 
79  if( this->getPostProcessingType() == postProcessing->getPostProcessingType() ){
80 
81  ClassLabelChangeFilter *ptr = (ClassLabelChangeFilter*)postProcessing;
82 
83  //Clone the ClassLabelChangeFilter values
84  this->filteredClassLabel = ptr->filteredClassLabel;
85  this->labelChanged = ptr->labelChanged;
86 
87  //Clone the post processing base variables
88  copyBaseVariables( postProcessing );
89  return true;
90  }
91  return false;
92 }
93 
95 
96  if( !initialized ){
97  errorLog << "process(const VectorDouble &inputVector) - Not initialized!" << std::endl;
98  return false;
99  }
100 
101  if( inputVector.getSize() != numInputDimensions ){
102  errorLog << "process(const VectorDouble &inputVector) - The size of the inputVector (" << inputVector.getSize() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
103  return false;
104  }
105 
106  //Use only the first value (as that is the predicted class label)
107  processedData[0] = filter( (UINT)inputVector[0] );
108  return true;
109 }
110 
112  filteredClassLabel = 0;
113  labelChanged = false;
114  processedData.clear();
115  processedData.resize(1,0);
116  return true;
117 }
118 
120 
121  initialized = false;
122 
123  reset();
124  numInputDimensions = 1;
125  numOutputDimensions = 1;
126  initialized = true;
127  return true;
128 }
129 
130 UINT ClassLabelChangeFilter::filter(UINT predictedClassLabel){
131 
132  labelChanged = false;
133 
134  if( predictedClassLabel != filteredClassLabel ){
135  filteredClassLabel = predictedClassLabel;
136  labelChanged = true;
137  return filteredClassLabel;
138  }
139 
140  return GRT_DEFAULT_NULL_CLASS_LABEL;
141 }
142 
143 bool ClassLabelChangeFilter::saveModelToFile( std::string filename ) const{
144 
145  if( !initialized ){
146  errorLog << "saveModelToFile(string filename) - The ClassLabelChangeFilter has not been initialized" << std::endl;
147  return false;
148  }
149 
150  std::fstream file;
151  file.open(filename.c_str(), std::ios::out);
152 
153  if( !saveModelToFile( file ) ){
154  file.close();
155  return false;
156  }
157 
158  file.close();
159 
160  return true;
161 }
162 
163 bool ClassLabelChangeFilter::saveModelToFile( std::fstream &file ) const{
164 
165  if( !file.is_open() ){
166  errorLog << "saveModelToFile(fstream &file) - The file is not open!" << std::endl;
167  return false;
168  }
169 
170  file << "GRT_CLASS_LABEL_CHANGE_FILTER_FILE_V1.0" << std::endl;
171  file << "NumInputDimensions: " << numInputDimensions << std::endl;
172  file << "NumOutputDimensions: " << numOutputDimensions << std::endl;
173 
174  return true;
175 }
176 
177 bool ClassLabelChangeFilter::loadModelFromFile( std::string filename ){
178 
179  std::fstream file;
180  file.open(filename.c_str(), std::ios::in);
181 
182  if( !loadModelFromFile( file ) ){
183  file.close();
184  return false;
185  }
186 
187  file.close();
188 
189  return true;
190 }
191 
192 bool ClassLabelChangeFilter::loadModelFromFile( std::fstream &file ){
193 
194  if( !file.is_open() ){
195  errorLog << "loadModelFromFile(fstream &file) - The file is not open!" << std::endl;
196  return false;
197  }
198 
199  std::string word;
200 
201  //Load the header
202  file >> word;
203 
204  if( word != "GRT_CLASS_LABEL_CHANGE_FILTER_FILE_V1.0" ){
205  errorLog << "loadModelFromFile(fstream &file) - Invalid file format!" << std::endl;
206  return false;
207  }
208 
209  file >> word;
210  if( word != "NumInputDimensions:" ){
211  errorLog << "loadModelFromFile(fstream &file) - Failed to read NumInputDimensions header!" << std::endl;
212  return false;
213  }
214  file >> numInputDimensions;
215 
216  //Load the number of output dimensions
217  file >> word;
218  if( word != "NumOutputDimensions:" ){
219  errorLog << "loadModelFromFile(fstream &file) - Failed to read NumOutputDimensions header!" << std::endl;
220  return false;
221  }
222  file >> numOutputDimensions;
223 
224  //Init the classLabelTimeoutFilter module to ensure everything is initialized correctly
225  return init();
226 }
227 
229  return labelChanged;
230 }
231 
232 GRT_END_NAMESPACE
ClassLabelChangeFilter & operator=(const ClassLabelChangeFilter &rhs)
virtual bool saveModelToFile(std::string filename) const
virtual bool loadModelFromFile(std::string filename)
std::string getPostProcessingType() const
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
unsigned int getSize() const
Definition: Vector.h:193
bool copyBaseVariables(const PostProcessing *postProcessingModule)
virtual bool deepCopyFrom(const PostProcessing *postProcessing)
UINT filter(UINT predictedClassLabel)
The Class Label Change Filter signals when the predicted output of a classifier changes. For instance, if the output stream of a classifier was {1,1,1,1,2,2,2,2,3,3}, then the output of the filter would be {1,0,0,0,2,0,0,0,3,0}. This module is useful if you want to debounce a gesture and only care about when the gesture label changes.
virtual bool process(const VectorDouble &inputVector)