GestureRecognitionToolkit  Version: 0.2.5
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
ClassificationModulesExamples/ANBCExample/ANBCExample.cpp

This class implements the Adaptive Naive Bayes Classifier algorithm. The Adaptive Naive Bayes Classifier (ANBC) is a naive but powerful classifier that works very well on both basic and more complex recognition problems.The ANBC algorithm is a supervised learning algorithm that can be used to classify any type of N-dimensional signal. The ANBC algorithm essentially works by fitting an N-dimensional Gaussian distribution to each class (i.e. gesture) during the training phase. New gestures can then be recognized in the prediction phase by finding the gesture that results in the maximum likelihood value (given the new sensor data and each of the Gaussian distributions). The ANBC algorithm also computes rejection thresholds that enable the algorithm to automatically reject sensor values that are not the K gestures the algorithm has been trained to recognized (without being explicitly told during the prediction phase if a gesture is, or is not, being performed).

In addition, the ANBC algorithm enables you to weight the importance of each dimension for each gesture. For instance, imagine that you want to create a recognition system that can recognize a user's left-handed gestures, right-handed gestures, and two-handed gestures. To track the user's movements you use a depth sensor and skeleton-tracking algorithm that can track any user who stands in front of the depth sensor and sends out the x-y-z joint position of the user's two hands (along with the user's other joints) at 30Hz. You use the 3-dimensional joint data for each hand to create a 6-dimensional vector (containing {leftHandX, leftHandY, leftHandZ, rightHandX, rightHandY, rightHandZ}) as input to the ANBC algorithm. The ANBC algorithm enables you to weight each dimension of this vector for each of the 3 types of gestures you want to recognize (i.e. left-handed, right-handed, and two-handed gestures), so for a left-handed gesture you would set the weights for this class to {1,1,1,0,0,0}, for the right-handed gesture you would set the weights for this class to {0,0,0,1,1,1}, and for the two-handed gesture you would set the weights for this class to {1,1,1,1,1,1}. You only need to set these weights values once, before you train the ANBC model, the weights will then automatically be incorporated into the Gaussian models for each gesture (and therefore nothing special needs to be done for the prediction phase). You can set the weights using the setWeights(LabelledClassificationData weightsData) function.

The ANBC algorithm is part of the GRT classification modules.

Remarks
You can find out more about the ANBC algorithm in ANBC.pdf.
/*
GRT ANBC Example
This examples demonstrates how to initialize, train, and use the ANBC algorithm for classification.
The Adaptive Naive Bayes Classifier (ANBC) is a naive but powerful classifier that works very well on both basic and more complex recognition problems.
In this example we create an instance of an ANBC algorithm and then train the algorithm using some pre-recorded training data.
The trained ANBC algorithm is then used to predict the class label of some test data.
This example shows you how to:
- Create an initialize the ANBC algorithm
- Load some ClassificationData from a file and partition the training data into a training dataset and a test dataset
- Train the ANBC algorithm using the training dataset
- Test the ANBC algorithm using the test dataset
- Manually compute the accuracy of the classifier
You should run this example with one argument pointing to the data you want to load. A good dataset to run this example is acc-orientation.grt, which can be found in the GRT data folder.
*/
//You might need to set the specific path of the GRT header relative to your project
#include <GRT/GRT.h>
using namespace GRT;
using namespace std;
int main (int argc, const char * argv[])
{
//Parse the data filename from the argument list
if( argc != 2 ){
cout << "Error: failed to parse data filename from command line. You should run this example with one argument pointing to the data filename!\n";
return EXIT_FAILURE;
}
const string filename = argv[1];
//Create a new ANBC instance
ANBC anbc;
anbc.enableScaling( true );
anbc.enableNullRejection( true );
//Load some training data to train the classifier
ClassificationData trainingData;
if( !trainingData.load( filename ) ){
cout << "Failed to load training data: " << filename << endl;
return EXIT_FAILURE;
}
//Use 20% of the training dataset to create a test dataset
ClassificationData testData = trainingData.split( 80 );
//Train the classifier
if( !anbc.train( trainingData ) ){
cout << "Failed to train classifier!\n";
return EXIT_FAILURE;
}
//Save the ANBC model to a file
if( !anbc.save("ANBCModel.grt") ){
cout << "Failed to save the classifier model!\n";
return EXIT_FAILURE;
}
//Load the ANBC model from a file
if( !anbc.load("ANBCModel.grt") ){
cout << "Failed to load the classifier model!\n";
return EXIT_FAILURE;
}
//Use the test dataset to test the ANBC model
double accuracy = 0;
for(UINT i=0; i<testData.getNumSamples(); i++){
//Get the i'th test sample
UINT classLabel = testData[i].getClassLabel();
VectorFloat inputVector = testData[i].getSample();
//Perform a prediction using the classifier
bool predictSuccess = anbc.predict( inputVector );
if( !predictSuccess ){
cout << "Failed to perform prediction for test sampel: " << i <<"\n";
return EXIT_FAILURE;
}
//Get the predicted class label
UINT predictedClassLabel = anbc.getPredictedClassLabel();
VectorFloat classLikelihoods = anbc.getClassLikelihoods();
VectorFloat classDistances = anbc.getClassDistances();
//Update the accuracy
if( classLabel == predictedClassLabel ) accuracy++;
cout << "TestSample: " << i << " ClassLabel: " << classLabel << " PredictedClassLabel: " << predictedClassLabel << endl;
}
cout << "Test Accuracy: " << accuracy/double(testData.getNumSamples())*100.0 << "%" << endl;
return EXIT_SUCCESS;
}