00001 #include <iostream>
00002 #include <fstream>
00003 #include <string>
00004 #include <sstream>
00005 #include <vector>
00006 #include <cmath>
00007
00008 #include "Learn/WiimoteGR/Quantizer.h"
00009 #include "Learn/WiimoteGR/HMMLib.h"
00010 #include "Learn/WiimoteGR/Database.h"
00011 #include "Image/Point2D.H"
00012
00013 using namespace std;
00014 using namespace WiimoteGR;
00015
00016 std::vector<Point2D<int> > square()
00017 {
00018 std::vector<Point2D<int> > acc;
00019 acc.push_back(Point2D<int>(5,0));
00020 acc.push_back(Point2D<int>(5,0));
00021 acc.push_back(Point2D<int>(5,0));
00022 acc.push_back(Point2D<int>(5,0));
00023 acc.push_back(Point2D<int>(0,0));
00024 acc.push_back(Point2D<int>(0,0));
00025 acc.push_back(Point2D<int>(0,0));
00026 acc.push_back(Point2D<int>(0,0));
00027 acc.push_back(Point2D<int>(-5,0));
00028 acc.push_back(Point2D<int>(-5,0));
00029 acc.push_back(Point2D<int>(-5,0));
00030 acc.push_back(Point2D<int>(-5,0));
00031
00032 acc.push_back(Point2D<int>(0,5));
00033 acc.push_back(Point2D<int>(0,5));
00034 acc.push_back(Point2D<int>(0,5));
00035 acc.push_back(Point2D<int>(0,5));
00036 acc.push_back(Point2D<int>(0,0));
00037 acc.push_back(Point2D<int>(0,0));
00038 acc.push_back(Point2D<int>(0,0));
00039 acc.push_back(Point2D<int>(0,0));
00040 acc.push_back(Point2D<int>(0,-5));
00041 acc.push_back(Point2D<int>(0,-5));
00042 acc.push_back(Point2D<int>(0,-5));
00043 acc.push_back(Point2D<int>(0,-5));
00044
00045 acc.push_back(Point2D<int>(-5,0));
00046 acc.push_back(Point2D<int>(-5,0));
00047 acc.push_back(Point2D<int>(-5,0));
00048 acc.push_back(Point2D<int>(-5,0));
00049 acc.push_back(Point2D<int>(0,0));
00050 acc.push_back(Point2D<int>(0,0));
00051 acc.push_back(Point2D<int>(0,0));
00052 acc.push_back(Point2D<int>(0,0));
00053 acc.push_back(Point2D<int>(5,0));
00054 acc.push_back(Point2D<int>(5,0));
00055 acc.push_back(Point2D<int>(5,0));
00056 acc.push_back(Point2D<int>(5,0));
00057
00058 acc.push_back(Point2D<int>(0,-5));
00059 acc.push_back(Point2D<int>(0,-5));
00060 acc.push_back(Point2D<int>(0,-5));
00061 acc.push_back(Point2D<int>(0,-5));
00062 acc.push_back(Point2D<int>(0,0));
00063 acc.push_back(Point2D<int>(0,0));
00064 acc.push_back(Point2D<int>(0,0));
00065 acc.push_back(Point2D<int>(0,0));
00066 acc.push_back(Point2D<int>(0,5));
00067 acc.push_back(Point2D<int>(0,5));
00068 acc.push_back(Point2D<int>(0,5));
00069 acc.push_back(Point2D<int>(0,5));
00070
00071 acc.push_back(Point2D<int>(0,0));
00072 acc.push_back(Point2D<int>(0,0));
00073 acc.push_back(Point2D<int>(0,0));
00074 acc.push_back(Point2D<int>(0,0));
00075
00076 return acc;
00077
00078 }
00079
00080 std::vector<Point2D<int> > triangle()
00081 {
00082 std::vector<Point2D<int> > acc;
00083 acc.push_back(Point2D<int>(5,0));
00084 acc.push_back(Point2D<int>(5,0));
00085 acc.push_back(Point2D<int>(5,0));
00086 acc.push_back(Point2D<int>(5,0));
00087 acc.push_back(Point2D<int>(0,0));
00088 acc.push_back(Point2D<int>(0,0));
00089 acc.push_back(Point2D<int>(0,0));
00090 acc.push_back(Point2D<int>(0,0));
00091 acc.push_back(Point2D<int>(-5,0));
00092 acc.push_back(Point2D<int>(-5,0));
00093 acc.push_back(Point2D<int>(-5,0));
00094 acc.push_back(Point2D<int>(-5,0));
00095
00096 acc.push_back(Point2D<int>(-5,5));
00097 acc.push_back(Point2D<int>(-5,5));
00098 acc.push_back(Point2D<int>(0,0));
00099 acc.push_back(Point2D<int>(0,0));
00100 acc.push_back(Point2D<int>(0,0));
00101 acc.push_back(Point2D<int>(0,0));
00102 acc.push_back(Point2D<int>(0,0));
00103 acc.push_back(Point2D<int>(0,0));
00104 acc.push_back(Point2D<int>(5,-5));
00105 acc.push_back(Point2D<int>(5,-5));
00106
00107 acc.push_back(Point2D<int>(-5,-5));
00108 acc.push_back(Point2D<int>(-5,-5));
00109 acc.push_back(Point2D<int>(0,0));
00110 acc.push_back(Point2D<int>(0,0));
00111 acc.push_back(Point2D<int>(0,0));
00112 acc.push_back(Point2D<int>(0,0));
00113 acc.push_back(Point2D<int>(0,0));
00114 acc.push_back(Point2D<int>(0,0));
00115 acc.push_back(Point2D<int>(5,5));
00116 acc.push_back(Point2D<int>(5,5));
00117
00118 acc.push_back(Point2D<int>(0,0));
00119 acc.push_back(Point2D<int>(0,0));
00120 acc.push_back(Point2D<int>(0,0));
00121 acc.push_back(Point2D<int>(0,0));
00122
00123 return acc;
00124
00125 }
00126
00127
00128 void Training(Database& db, const Quantizer& quantizer, HMMLib& trainer, HMM& hmm);
00129
00130
00131 int main()
00132 {
00133
00134 const char* initGestureName = "unknown";
00135
00136 M32Quantizer defaultQuantizer;
00137 const double OP = 1.0/defaultQuantizer.M;
00138
00139 const char* initModelStyle = "5 state left to right";
00140
00141 bool initTrained = false;
00142
00143 const size_t initN = 5;
00144
00145 double initA[] = { 0.5, 0.5, 0.0, 0.0, 0.0,
00146 0.0, 0.5, 0.5, 0.0, 0.0,
00147 0.0, 0.0, 0.5, 0.5, 0.0,
00148 0.0, 0.0, 0.0, 0.5, 0.5,
00149 0.0, 0.0, 0.0, 0.0, 1.0
00150 };
00151
00152 double initB[] = { OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP,
00153 OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP,
00154 OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP,
00155 OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP,
00156 OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP, OP
00157 };
00158 double initPi[] = { 1.0, 0.0, 0.0, 0.0, 0.0};
00159
00160 HMM initHMM(initGestureName, defaultQuantizer, initModelStyle, initTrained, initN, initA, initB, initPi);
00161
00162
00163
00164 Database& db = Database::Open();
00165
00166
00167 HMMLib trainer;
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 cout << endl << "============================TESTING===============================" << endl;
00190 vector<HMM> loadedHMMVec;
00191
00192
00193 TimeSlot tempSeq("testingGesture",defaultQuantizer);
00194 Acceleration tempAcc;
00195
00196
00197 db.LoadHMMs(defaultQuantizer, initModelStyle, true, loadedHMMVec);
00198 cout << loadedHMMVec.size() << " pre saved HMM loaded for testing, now gestures are:" << endl;
00199 for(vector<HMM>::iterator i=loadedHMMVec.begin() ; i<loadedHMMVec.end(); i++)
00200 cout << i->gestureName << " ";
00201 cout << endl;
00202
00203 cout << "Start recognition of " << loadedHMMVec.size() << " gesture models." << endl;
00204
00205 std::vector<Point2D<int> > acc = triangle();
00206
00207
00208 for(size_t i=0; i<acc.size(); i++)
00209 {
00210 tempAcc.x=acc[i].i;
00211 tempAcc.y=acc[i].j;
00212 tempAcc.z=0;
00213
00214 tempSeq.AddObservableSymbol(defaultQuantizer.Quantize(tempAcc));
00215
00216
00217 cout << trainer.Recognize(loadedHMMVec,tempSeq).gestureName << "-> ";
00218 }
00219
00220
00221 cout << endl;
00222 for(size_t i = 0; i < loadedHMMVec.size(); i++)
00223 cout << "Prob to " << loadedHMMVec[i].gestureName << " model = " << exp(trainer.SeqLogProb(loadedHMMVec[i],tempSeq,false)) << endl;
00224 tempSeq.ClearObservableSymbols();
00225
00226 return 0;
00227 }
00228
00229 void Training(Database& db, const Quantizer& quantizer,
00230 HMMLib& trainer, HMM& hmm){
00231
00232 size_t M = quantizer.M;
00233 if(hmm.M == M){
00234
00235 vector<Gesture> gestureVec;
00236
00237 vector<TimeSlot> seqVec;
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 db.DeleteGestures(hmm.gestureName.c_str());
00248 db.DeleteObservationSequences(hmm.gestureName.c_str(),quantizer);
00249 cout << "Sequences of gesture " << hmm.gestureName << " deleted from database." << endl;
00250
00251
00252 Gesture tempGesture(hmm.gestureName.c_str());
00253
00254 trainer.ShowHMM(hmm);
00255 std::vector<Point2D<int> > acc;
00256 if (hmm.gestureName == "square")
00257 acc = square();
00258 else
00259 acc = triangle();
00260
00261
00262
00263
00264 for(size_t j=0; j<acc.size(); j++)
00265 {
00266
00267 for(size_t i=0; i<acc.size(); i++)
00268 {
00269 Acceleration tempAcc;
00270 tempAcc.x=acc[(j+i)%acc.size()].i;
00271 tempAcc.y=acc[(j+i)%acc.size()].j;
00272 tempAcc.z=0;
00273
00274 tempGesture.data.push_back(tempAcc);
00275 cout.width(3);
00276 cout << quantizer.Quantize(tempAcc) << " ";
00277 }
00278
00279 TimeSlot tempSeq(hmm.gestureName.c_str(), quantizer);
00280
00281 quantizer.Quantize(tempGesture,tempSeq);
00282 cout << "/ Length = " << tempSeq.o.size() << endl << endl;
00283
00284 gestureVec.push_back(tempGesture);
00285 seqVec.push_back(tempSeq);
00286
00287 db.SaveGesture(tempGesture);
00288 db.SaveObservationSequence(tempSeq);
00289 tempGesture.data.clear();
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299 for(size_t i = 0; i < seqVec.size(); i++)
00300 cout << "prob of seqs[" << i << "] to " << hmm.gestureName << " model = " << trainer.SeqLogProb(hmm,seqVec[i],false) << endl;
00301
00302 cout << hmm.gestureName << " gesture model is trained in " << trainer.EstimateModelBySeqs(hmm, seqVec, 50) << " loops" << endl;
00303
00304 hmm.trained = true;
00305 trainer.ShowHMM(hmm);
00306 db.SaveHMM(hmm);
00307
00308
00309 for(size_t i = 0; i < seqVec.size(); i++)
00310 cout << "prob of seqs[" << i << "] to " << hmm.gestureName << " model = " << trainer.SeqLogProb(hmm,seqVec[i],false) << endl;
00311
00312 }else{
00313 cout << "ERROR hmm.M != quantizer.M" << endl;
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383