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