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.
Classifier.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 "Classifier.h"
22 
23 GRT_BEGIN_NAMESPACE
24 
25 Classifier::StringClassifierMap* Classifier::stringClassifierMap = NULL;
26 UINT Classifier::numClassifierInstances = 0;
27 
28 Classifier* Classifier::createInstanceFromString(std::string const &classifierType){
29 
30  StringClassifierMap::iterator iter = getMap()->find( classifierType );
31  if( iter == getMap()->end() ){
32  return NULL;
33  }
34  return iter->second();
35 }
37  return createInstanceFromString( classifierType );
38 }
39 
41 
42  Classifier *newInstance = createInstanceFromString( classifierType );
43 
44  if( newInstance == NULL ) return NULL;
45 
46  if( !newInstance->deepCopyFrom( this ) ){
47  delete newInstance;
48  return NULL;
49  }
50  return newInstance;
51 }
52 
54  return this;
55 }
56 
58  Vector< std::string > registeredClassifiers;
59 
60  StringClassifierMap::iterator iter = getMap()->begin();
61  while( iter != getMap()->end() ){
62  registeredClassifiers.push_back( iter->first );
63  iter++;
64  }
65  return registeredClassifiers;
66 }
67 
69  baseType = MLBase::CLASSIFIER;
70  classifierMode = STANDARD_CLASSIFIER_MODE;
71  classifierType = "NOT_SET";
72  supportsNullRejection = false;
73  useNullRejection = false;
74  numInputDimensions = 0;
75  numOutputDimensions = 1;
76  numClasses = 0;
77  predictedClassLabel = 0;
78  maxLikelihood = 0;
79  bestDistance = 0;
80  phase = 0;
81  nullRejectionCoeff = 5;
82  numClassifierInstances++;
83 }
84 
86  if( --numClassifierInstances == 0 ){
87  delete stringClassifierMap;
88  stringClassifierMap = NULL;
89  }
90 }
91 
92 bool Classifier::copyBaseVariables(const Classifier *classifier){
93 
94  if( classifier == NULL ){
95  errorLog << "copyBaseVariables(const Classifier *classifier) - Classifier is NULL!" << std::endl;
96  return false;
97  }
98 
99  if( !this->copyMLBaseVariables( classifier ) ){
100  return false;
101  }
102 
103  this->classifierType = classifier->classifierType;
104  this->classifierMode = classifier->classifierMode;
105  this->supportsNullRejection = classifier->supportsNullRejection;
106  this->useNullRejection = classifier->useNullRejection;
107  this->numClasses = classifier->numClasses;
108  this->predictedClassLabel = classifier->predictedClassLabel;
109  this->nullRejectionCoeff = classifier->nullRejectionCoeff;
110  this->maxLikelihood = classifier->maxLikelihood;
111  this->bestDistance = classifier->bestDistance;
112  this->phase = classifier->phase;
113  this->classLabels = classifier->classLabels;
114  this->classLikelihoods = classifier->classLikelihoods;
115  this->classDistances = classifier->classDistances;
116  this->nullRejectionThresholds = classifier->nullRejectionThresholds;
117  this->ranges = classifier->ranges;
118 
119  return true;
120 }
121 
123 
124  //Reset the base class
125  MLBase::reset();
126 
127  //Reset the classifier
128  predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL;
129  maxLikelihood = 0;
130  bestDistance = 0;
131  phase = 0;
132  if( trained ){
133  classLikelihoods.clear();
134  classDistances.clear();
135  classLikelihoods.resize(numClasses,0);
136  classDistances.resize(numClasses,0);
137  }
138  return true;
139 }
140 
142 
143  //Clear the MLBase variables
144  MLBase::clear();
145 
146  //Clear the classifier variables
147  predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL;
148  maxLikelihood = 0;
149  bestDistance = 0;
150  phase = 0;
151  classLikelihoods.clear();
152  classDistances.clear();
153  nullRejectionThresholds.clear();
154  classLabels.clear();
155  ranges.clear();
156 
157  return true;
158 }
159 
160 std::string Classifier::getClassifierType() const{
161  return classifierType;
162 }
163 
165  return supportsNullRejection;
166 }
167 
169  return useNullRejection;
170 }
171 
173  return nullRejectionCoeff;
174 }
175 
177  if( trained ) return maxLikelihood;
179 }
180 
181 Float Classifier::getPhase() const{
182  return phase;
183 }
184 
186  if( trained ) return bestDistance;
187  return DEFAULT_NULL_DISTANCE_VALUE;
188 }
189 
191  return numClasses;
192 }
193 
194 UINT Classifier::getClassLabelIndexValue(UINT classLabel) const{
195  for(UINT i=0; i<classLabels.size(); i++){
196  if( classLabel == classLabels[i] )
197  return i;
198  }
199  return 0;
200 }
201 
203  if( trained ) return predictedClassLabel;
204  return 0;
205 }
206 
208  if( trained ) return classLikelihoods;
209  return VectorFloat();
210 }
211 
213  if( trained ) return classDistances;
214  return VectorFloat();
215 }
216 
218  if( trained ) return nullRejectionThresholds;
219  return VectorFloat();
220 }
221 
223  return classLabels;
224 }
225 
227  return ranges;
228 }
229 
230 bool Classifier::enableNullRejection(bool useNullRejection){
231  this->useNullRejection = useNullRejection;
232  return true;
233 }
234 
235 bool Classifier::setNullRejectionCoeff(Float nullRejectionCoeff){
236  if( nullRejectionCoeff > 0 ){
237  this->nullRejectionCoeff = nullRejectionCoeff;
238  return true;
239  }
240  return false;
241 }
242 
244  if( newRejectionThresholds.size() == getNumClasses() ){
245  nullRejectionThresholds = newRejectionThresholds;
246  return true;
247  }
248  return false;
249 }
250 
252  return *this;
253 }
254 
255 bool Classifier::saveBaseSettingsToFile( std::fstream &file ) const{
256 
257  if( !file.is_open() ){
258  errorLog << "saveBaseSettingsToFile(fstream &file) - The file is not open!" << std::endl;
259  return false;
260  }
261 
262  if( !MLBase::saveBaseSettingsToFile( file ) ) return false;
263 
264  file << "UseNullRejection: " << useNullRejection << std::endl;
265  file << "ClassifierMode: " << classifierMode << std::endl;
266  file << "NullRejectionCoeff: " << nullRejectionCoeff << std::endl;
267 
268  if( trained ){
269 
270  file << "NumClasses: " << numClasses << std::endl;
271 
272  file << "NullRejectionThresholds: ";
273  if (useNullRejection && nullRejectionThresholds.size()){
274  for(UINT i=0; i<nullRejectionThresholds.size(); i++){
275  file << " " << nullRejectionThresholds[i];
276  }
277  file << std::endl;
278  }else{
279  for(UINT i=0; i<numClasses; i++){
280  file << " " << 0.0;
281  }
282  file << std::endl;
283  }
284 
285  file << "ClassLabels: ";
286  for(UINT i=0; i<classLabels.size(); i++){
287  file << " " << classLabels[i];
288  }
289  file << std::endl;
290 
291  if( useScaling ){
292  file << "Ranges: " << std::endl;
293  for(UINT i=0; i<ranges.size(); i++){
294  file << ranges[i].minValue << "\t" << ranges[i].maxValue << std::endl;
295  }
296  }
297  }
298 
299  return true;
300 }
301 
302 bool Classifier::loadBaseSettingsFromFile( std::fstream &file ){
303 
304  if( !file.is_open() ){
305  errorLog << "loadBaseSettingsFromFile(fstream &file) - The file is not open!" << std::endl;
306  return false;
307  }
308 
309  //Try and load the base settings from the file
310  if( !MLBase::loadBaseSettingsFromFile( file ) ){
311  return false;
312  }
313 
314  std::string word;
315 
316  //Load if the number of clusters
317  file >> word;
318  if( word != "UseNullRejection:" ){
319  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read UseNullRejection header!" << std::endl;
320  clear();
321  return false;
322  }
323  file >> useNullRejection;
324 
325  //Load if the classifier mode
326  file >> word;
327  if( word != "ClassifierMode:" ){
328  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read ClassifierMode header!" << std::endl;
329  clear();
330  return false;
331  }
332  file >> classifierMode;
333 
334  //Load if the null rejection coeff
335  file >> word;
336  if( word != "NullRejectionCoeff:" ){
337  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NullRejectionCoeff header!" << std::endl;
338  clear();
339  return false;
340  }
341  file >> nullRejectionCoeff;
342 
343  //If the model is trained then load the model settings
344  if( trained ){
345 
346  //Load the number of classes
347  file >> word;
348  if( word != "NumClasses:" ){
349  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NumClasses header!" << std::endl;
350  clear();
351  return false;
352  }
353  file >> numClasses;
354 
355  //Load the null rejection thresholds
356  file >> word;
357  if( word != "NullRejectionThresholds:" ){
358  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NullRejectionThresholds header!" << std::endl;
359  clear();
360  return false;
361  }
362  nullRejectionThresholds.resize(numClasses);
363  for(UINT i=0; i<nullRejectionThresholds.size(); i++){
364  file >> nullRejectionThresholds[i];
365  }
366 
367  //Load the class labels
368  file >> word;
369  if( word != "ClassLabels:" ){
370  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read ClassLabels header!" << std::endl;
371  clear();
372  return false;
373  }
374  classLabels.resize( numClasses );
375  for(UINT i=0; i<classLabels.size(); i++){
376  file >> classLabels[i];
377  }
378 
379  if( useScaling ){
380  //Load if the Ranges
381  file >> word;
382  if( word != "Ranges:" ){
383  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read Ranges header!" << std::endl;
384  clear();
385  return false;
386  }
387  ranges.resize(numInputDimensions);
388 
389  for(UINT i=0; i<ranges.size(); i++){
390  file >> ranges[i].minValue;
391  file >> ranges[i].maxValue;
392  }
393  }
394  }
395 
396  return true;
397 }
398 
399 GRT_END_NAMESPACE
400 
bool saveBaseSettingsToFile(std::fstream &file) const
Definition: Classifier.cpp:255
bool saveBaseSettingsToFile(std::fstream &file) const
Definition: MLBase.cpp:370
#define DEFAULT_NULL_LIKELIHOOD_VALUE
Definition: Classifier.h:38
Classifier * deepCopy() const
Definition: Classifier.cpp:40
Vector< UINT > getClassLabels() const
Definition: Classifier.cpp:222
Vector< MinMax > getRanges() const
Definition: Classifier.cpp:226
virtual bool reset()
Definition: MLBase.cpp:124
VectorFloat getNullRejectionThresholds() const
Definition: Classifier.cpp:217
std::string getClassifierType() const
Definition: Classifier.cpp:160
virtual UINT getNumClasses() const
Definition: Classifier.cpp:190
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
const Classifier * getClassifierPointer() const
Definition: Classifier.cpp:53
Classifier(void)
Definition: Classifier.cpp:68
UINT getClassLabelIndexValue(UINT classLabel) const
Definition: Classifier.cpp:194
Float getNullRejectionCoeff() const
Definition: Classifier.cpp:172
virtual bool deepCopyFrom(const Classifier *classifier)
Definition: Classifier.h:61
bool getSupportsNullRejection() const
Definition: Classifier.cpp:164
virtual bool setNullRejectionThresholds(VectorFloat newRejectionThresholds)
Definition: Classifier.cpp:243
bool getNullRejectionEnabled() const
Definition: Classifier.cpp:168
Float getPhase() const
Definition: Classifier.cpp:181
UINT getPredictedClassLabel() const
Definition: Classifier.cpp:202
bool copyMLBaseVariables(const MLBase *mlBase)
Definition: MLBase.cpp:49
Float getBestDistance() const
Definition: Classifier.cpp:185
static Classifier * createInstanceFromString(std::string const &classifierType)
Definition: Classifier.cpp:28
bool copyBaseVariables(const Classifier *classifier)
Definition: Classifier.cpp:92
virtual ~Classifier(void)
Definition: Classifier.cpp:85
bool loadBaseSettingsFromFile(std::fstream &file)
Definition: Classifier.cpp:302
Float getMaximumLikelihood() const
Definition: Classifier.cpp:176
This is the main base class that all GRT Classification algorithms should inherit from...
bool loadBaseSettingsFromFile(std::fstream &file)
Definition: MLBase.cpp:393
virtual bool setNullRejectionCoeff(Float nullRejectionCoeff)
Definition: Classifier.cpp:235
virtual bool reset()
Definition: Classifier.cpp:122
virtual bool clear()
Definition: MLBase.cpp:126
VectorFloat getClassDistances() const
Definition: Classifier.cpp:212
static Vector< std::string > getRegisteredClassifiers()
Definition: Classifier.cpp:57
VectorFloat getClassLikelihoods() const
Definition: Classifier.cpp:207
std::map< std::string, Classifier *(*)() > StringClassifierMap
Definition: Classifier.h:248
bool enableNullRejection(bool useNullRejection)
Definition: Classifier.cpp:230
Definition: Vector.h:41
virtual bool clear()
Definition: Classifier.cpp:141
Classifier * createNewInstance() const
Definition: Classifier.cpp:36
const Classifier & getBaseClassifier() const
Definition: Classifier.cpp:251