GestureRecognitionToolkit  Version: 1.0 Revision: 04-03-15
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
MeanShift.h
Go to the documentation of this file.
1 
33 #ifndef GRT_MEAN_SHIFT_HEADER
34 #define GRT_MEAN_SHIFT_HEADER
35 
36 #include "../../CoreModules/MLBase.h"
37 
38 namespace GRT {
39 
40 class MeanShift : public MLBase{
41 public:
42  MeanShift() {
43  classType = "MeanShift";
44  infoLog.setProceedingText("[MeanShift]");
45  debugLog.setProceedingText("[DEBUG MeanShift]");
46  errorLog.setProceedingText("[ERROR MeanShift]");
47  trainingLog.setProceedingText("[TRAINING MeanShift]");
48  warningLog.setProceedingText("[WARNING MeanShift]");
49  }
50 
51  virtual ~MeanShift(){
52 
53  }
54 
55  bool search( const VectorDouble &meanStart, const vector< VectorDouble > &points, const double searchRadius, const double sigma = 20.0 ){
56 
57  //clear the results from any previous search
58  clear();
59 
60  const unsigned int numDimensions = (unsigned int)meanStart.size();
61  const unsigned int numPoints = (unsigned int)points.size();
62  const double gamma = 1.0 / (2 * SQR(sigma) );
63  unsigned int iteration = 0;
64  VectorDouble numer(2,0);
65  VectorDouble denom(2,0);
66  VectorDouble kernelDist(2,0);
67  double pointsWithinSearchRadius = 0;
68 
69  mean = meanStart;
70  VectorDouble lastMean = mean;
71 
72  //Start the search loop
73  while( true ){
74 
75  //Reset the counters
76  pointsWithinSearchRadius = 0;
77  std::fill(numer.begin(),numer.end(),0);
78  std::fill(denom.begin(),denom.end(),0);
79  std::fill(kernelDist.begin(),kernelDist.end(),0);
80 
81  //Update the numerator and denominator for points that are with the search radius
82  for(unsigned int i=0; i<numPoints; i++){
83 
84  //Compute the distance of the current point to the mean
85  double distToMean = euclideanDist( mean, points[i] );
86 
87  //If the point is within the search radius then update numer and denom
88  if( distToMean < searchRadius ){
89 
90  for(unsigned int j=0; j<numDimensions; j++){
91  kernelDist[j] = gaussKernel( points[i][j], mean[j], gamma );
92  numer[j] += kernelDist[j] * points[i][j];
93  denom[j] += kernelDist[j];
94  }
95 
96  pointsWithinSearchRadius++;
97  }
98  }
99 
100  //Update the mean
101  double change = 0;
102  for(unsigned int j=0; j<numDimensions; j++){
103 
104  mean[j] = numer[j] / denom[j];
105 
106  change += SQR( mean[j] - lastMean[j] );
107 
108  lastMean[j] = mean[j];
109  }
110  change = sqrt( change );
111 
112  trainingLog << "iteration: " << iteration;
113  trainingLog << " mean: ";
114  for(unsigned int j=0; j<numDimensions; j++){
115  trainingLog << mean[j] << " ";
116  }
117  trainingLog << " change: " << change << endl;
118 
119  if( change < minChange ){
120  trainingLog << "min changed limit reached - stopping search" << endl;
121  break;
122  }
123 
124  if( ++iteration >= maxNumEpochs ){
125  trainingLog << "max number of iterations reached - stopping search." << endl;
126  break;
127  }
128 
129  }
130  numTrainingIterationsToConverge = iteration;
131  trained = true;
132 
133  return true;
134  }
135 
136  VectorDouble getMean() const {
137  return mean;
138  }
139 
140  double gaussKernel( const double &x, const double &mu, const double gamma ){
141  return exp( gamma * SQR(x-mu) );
142  }
143 
144  double gaussKernel( const VectorDouble &x, const VectorDouble &mu, const double gamma ){
145 
146  double y = 0;
147  const size_t N = x.size();
148  for(size_t i=0; i<N; i++){
149  y += SQR(x[i]-mu[i]);
150  }
151  return exp( gamma * y );
152  }
153 
154  double euclideanDist( const VectorDouble &x, const VectorDouble &y ){
155 
156  double z = 0;
157  const size_t N = x.size();
158  for(size_t i=0; i<N; i++){
159  z += SQR(x[i]-y[i]);
160  }
161  return sqrt( z );
162 
163  }
164 
165 protected:
166 
167  VectorDouble mean;
168 
169 };
170 
171 }
172 
173 #endif //GRT_MEAN_SHIFT_HEADER
virtual bool clear()
Definition: MLBase.cpp:118
Definition: AdaBoost.cpp:25