// // GVFGesture.h // gvf // // Created by Baptiste Caramiaux on 22/01/16. // // #ifndef GVFGesture_h #define GVFGesture_h #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif class GVFGesture { public: GVFGesture() { inputDimensions = 2; setAutoAdjustRanges(true); templatesRaw = vector<vector<vector<float > > >(); templatesNormal = vector<vector<vector<float > > >(); clear(); } GVFGesture(int inputDimension){ inputDimensions = inputDimension; setAutoAdjustRanges(true); templatesRaw = vector<vector<vector<float > > >(); templatesNormal = vector<vector<vector<float > > >(); clear(); } ~GVFGesture(){ clear(); } void setNumberDimensions(int dimensions){ assert(dimensions > 0); inputDimensions = dimensions; } void setAutoAdjustRanges(bool b){ // if(b) bIsRangeMinSet = bIsRangeMaxSet = false; bAutoAdjustNormalRange = b; } void setMax(float x, float y){ assert(inputDimensions == 2); vector<float> r(2); r[0] = x; r[1] = y; setMaxRange(r); } void setMin(float x, float y){ assert(inputDimensions == 2); vector<float> r(2); r[0] = x; r[1] = y; setMinRange(r); } void setMax(float x, float y, float z){ assert(inputDimensions == 3); vector<float> r(3); r[0] = x; r[1] = y; r[2] = z; setMaxRange(r); } void setMin(float x, float y, float z){ assert(inputDimensions == 3); vector<float> r(3); r[0] = x; r[1] = y; r[2] = z; setMinRange(r); } void setMaxRange(vector<float> observationRangeMax){ this->observationRangeMax = observationRangeMax; // bIsRangeMaxSet = true; normalise(); } void setMinRange(vector<float> observationRangeMin){ this->observationRangeMin = observationRangeMin; // bIsRangeMinSet = true; normalise(); } vector<float>& getMaxRange(){ return observationRangeMax; } vector<float>& getMinRange(){ return observationRangeMin; } void autoAdjustMinMax(vector<float> & observation){ if(observationRangeMax.size() < inputDimensions){ observationRangeMax.assign(inputDimensions, -INFINITY); observationRangeMin.assign(inputDimensions, INFINITY); } for(int i = 0; i < inputDimensions; i++){ observationRangeMax[i] = MAX(observationRangeMax[i], observation[i]); observationRangeMin[i] = MIN(observationRangeMin[i], observation[i]); } } void addObservation(vector<float> observation, int templateIndex = 0){ if (observation.size() != inputDimensions) inputDimensions = int(observation.size()); // check we have a valid templateIndex and correct number of input dimensions assert(templateIndex <= templatesRaw.size()); assert(observation.size() == inputDimensions); // if the template index is same as the number of temlates make a new template if(templateIndex == templatesRaw.size()){ // make a new template // reserve space in raw and normal template storage templatesRaw.resize(templatesRaw.size() + 1); templatesNormal.resize(templatesNormal.size() + 1); } if(templatesRaw[templateIndex].size() == 0) { templateInitialObservation = observation; templateInitialNormal = observation; } for(int j = 0; j < observation.size(); j++) observation[j] = observation[j] - templateInitialObservation[j]; // store the raw observation templatesRaw[templateIndex].push_back(observation); autoAdjustMinMax(observation); normalise(); } void normalise() { templatesNormal.resize(templatesRaw.size()); for(int t = 0; t < templatesRaw.size(); t++) { templatesNormal[t].resize(templatesRaw[t].size()); for(int o = 0; o < templatesRaw[t].size(); o++) { templatesNormal[t][o].resize(inputDimensions); for(int d = 0; d < inputDimensions; d++) { templatesNormal[t][o][d] = templatesRaw[t][o][d] / (observationRangeMax[d] - observationRangeMin[d]); templateInitialNormal[d] = templateInitialObservation[d] / (observationRangeMax[d] - observationRangeMin[d]); } } } } void setTemplate(vector< vector<float> > & observations, int templateIndex = 0){ for(int i = 0; i < observations.size(); i++){ addObservation(observations[i], templateIndex); } } vector< vector<float> > & getTemplate(int templateIndex = 0){ assert(templateIndex < templatesRaw.size()); return templatesRaw[templateIndex]; } int getNumberOfTemplates(){ return int(templatesRaw.size()); } int getNumberDimensions(){ return inputDimensions; } int getTemplateLength(int templateIndex = 0){ return int(templatesRaw[templateIndex].size()); } int getTemplateDimension(int templateIndex = 0){ return int(templatesRaw[templateIndex][0].size()); } vector<float>& getLastObservation(int templateIndex = 0){ return templatesRaw[templateIndex][templatesRaw[templateIndex].size() - 1]; } vector< vector< vector<float> > >& getTemplates(){ return templatesRaw; } vector<float>& getInitialObservation(){ return templateInitialObservation; } void deleteTemplate(int templateIndex = 0) { assert(templateIndex < templatesRaw.size()); templatesRaw[templateIndex].clear(); templatesNormal[templateIndex].clear(); } void clear() { templatesRaw.clear(); templatesNormal.clear(); observationRangeMax.assign(inputDimensions, -INFINITY); observationRangeMin.assign(inputDimensions, INFINITY); } private: int inputDimensions; bool bAutoAdjustNormalRange; vector<float> observationRangeMax; vector<float> observationRangeMin; vector<float> templateInitialObservation; vector<float> templateInitialNormal; vector< vector< vector<float> > > templatesRaw; vector< vector< vector<float> > > templatesNormal; vector<vector<float> > gestureDataFromFile; }; #endif /* GVFGesture_h */