root / src / gesture / Gestures.h @ 23

View | Annotate | Download (5.1 KB)

1
/*
2
 * Gestures.h
3
 *
4
 *  Created on: Jun 8, 2009
5
 *      Author: damaraju
6
 */
7
8
#ifndef GESTURES_H_
9
#define GESTURES_H_
10
11
#include <map>
12
#include <string>
13
#include <fstream>
14
15
#include <touch/Touch.h>
16
#include <gesture/models/VectorGestureClassification.h>
17
18
#include <boost/range/adaptor/transformed.hpp>
19
#include <boost/range/algorithm/copy.hpp>
20
#include <boost/archive/binary_oarchive.hpp>
21
#include <boost/archive/binary_iarchive.hpp>
22
#include <boost/serialization/vector.hpp>
23
24
using namespace std;
25
//For debug and test
26
string base = "data/reOrdered/";
27
28
void printTransform(vector<vector<double> > transformed)
29
{
30
        cout << "Transformed Size: " << transformed.size() << endl;
31
32
        for(size_t i = 0; i < transformed.size(); ++i)
33
        {
34
                for (size_t j = 0; j < transformed.at(i).size(); ++j)
35
                        cout << i << ": " << transformed.at(i).at(j) << "\t";
36
                cout << endl;
37
        }
38
}
39
40
vector<GestureSample> readFile(string fileName)
41
{
42
        vector<GestureSample> readSamples;
43
        ifstream readFile;
44
45
        cout << "Reading: " << fileName << " " << endl;
46
        readFile.open(fileName.c_str());
47
        string line;
48
49
50
        if (readFile.is_open())
51
        {
52
                while(!readFile.eof())
53
                {
54
                        getline(readFile,line);
55
                        GestureSample sample = GestureSample(line);
56
57
                        if(sample.size() > 0)
58
                                readSamples.push_back(sample);
59
                }
60
                cout << "Num Samples: " << readSamples.size() << endl;
61
                readFile.close();
62
        }
63
        else
64
        {
65
                cout << "Unable to read file: " << fileName << endl;
66
        }
67
        return readSamples;
68
69
}
70
vector<GestureSample> readGestureSet(string gid, string uid)
71
{
72
        string fileName = "gid_" + gid + "_uid_" + uid + ".seqs";
73
        return readFile(base + fileName);
74
}
75
76
77
vector<vector<vector<double> > > transformSamples(vector<GestureSample> samples)
78
{
79
        vector<vector<vector<double> > > transformedSet;
80
        //cout << "Transforming " << samples.size() << " samples" << endl;
81
82
        if (samples.size() > 0)
83
                for (size_t i = 0; i < samples.size(); ++i)
84
                        transformedSet.push_back(samples.at(i).transform());
85
        else
86
                cout << "No Samples" << endl;
87
88
        return transformedSet;
89
}
90
91
class RecognitionHelper
92
{
93
public:
94
        VectorGestureClassification classifier;
95
        map<int, string>                         gestureNameMap;
96
97
        RecognitionHelper()
98
        {}
99
        void trainWithSamples(vector<GestureSample> trainingSet, string gestureName)
100
        {
101
                VectorGestureClassification tempClassifier;
102
103
                vector<vector<vector<double> > > trnsfTrain = transformSamples(trainingSet);
104
                //Magical filter takes care of all preprocessing, and live processing of the incoming sample(s).
105
                multitouch_filter filter = multitouch_filter(trnsfTrain);
106
107
                //Ensure the training set is appropriately scaled for training the model.
108
                vector<vector<vector<double> > > filteredTraining = trnsfTrain;
109
                for(size_t i = 0; i < trnsfTrain.size() - 1; i++)
110
                {
111
                        filter.reset_params_for(trnsfTrain[i]);
112
                        boost::copy(trnsfTrain[i] | boost::adaptors::transformed(filter),filteredTraining[i].begin());
113
                }
114
115
                cout << "Training With: " << filteredTraining.size() << " samples" << endl;
116
                const unsigned int MIN_STATE_SIZE = 2;
117
                const unsigned int MAX_STATE_SIZE = 11;
118
                for(size_t i = MIN_STATE_SIZE; i <= MAX_STATE_SIZE; i++)
119
                        tempClassifier.addGestureWithExamplesAndFilter(filteredTraining, i, filter);
120
121
122
123
                int classIndex = tempClassifier.classify(trnsfTrain[trnsfTrain.size()-1]);
124
125
                vector<long double> probs = tempClassifier.probabilities();
126
                cout << "Probabilities for last sample is :: ";
127
                for(unsigned int i = 0 ; i < probs.size(); i++)
128
                        cout << probs[i] << ", ";
129
130
                classifier.addGestureWithExamplesAndFilter(filteredTraining, classIndex + MIN_STATE_SIZE, filter);
131
132
                gestureNameMap.insert(pair<int, string>(classifier.numGestures() - 1, gestureName));
133
                cout << "\nAdded new gesture(" << classifier.numGestures() - 1 << "): " << gestureName << " [" << classIndex + MIN_STATE_SIZE << " states]\n"<<endl;
134
        }
135
136
        string classify(GestureSample sample)
137
        {
138
                vector<vector<double> > transformed = sample.transform();
139
                //printTransform(transformed);
140
                int classIndex = classifier.classify(transformed);
141
                vector<long double> probs = classifier.probabilities();
142
143
                bool allZero = true;
144
                for(unsigned int i = 0 ; i < probs.size(); i++)
145
                {
146
                        if(probs[i] > 0)
147
                                allZero = false;
148
                        cout << probs[i] << ", ";
149
                }
150
                cout << endl;
151
152
                if(!allZero && classIndex >= 0 && ((unsigned int)classIndex) < gestureNameMap.size())
153
                        return gestureNameMap[classIndex];
154
                else //classIndex == -1 || allZero probabilities when sample doesn't match any filter-model pair
155
                        return "None";
156
        }
157
158
        const std::vector<long double> &probabilities() const
159
        {
160
            return classifier.probabilities();
161
        }
162
163
    friend class boost::serialization::access;
164
    template<class Archive>
165
    void serialize(Archive & ar, const unsigned int version)
166
    {
167
        ar & boost::serialization::base_object<RecognitionHelper>(*this);
168
        ar & classifier;
169
        ar & gestureNameMap;
170
    }
171
};
172
173
174
void saveGestureSet(const char* appName, RecognitionHelper &helper)
175
{
176
        ofstream storage(appName, ios::out | ios::binary);
177
        boost::archive::binary_oarchive out(storage);
178
179
        out << helper;
180
}
181
182
void readGestureSet(const char* appName, RecognitionHelper &helper)
183
{
184
        ifstream storage(appName, ios::in | ios::binary);
185
        boost::archive::binary_iarchive in(storage);
186
187
        in >> helper;
188
189
}
190
#endif /* GESTURES_H_ */