Home || Visual Search || Applications || Architecture || Important Messages || OGL || Src

Classifier.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Tracking_Classifier_h
00002 #define Impala_Core_Tracking_Classifier_h
00003 
00004 #include "Core/Array/Arrays.h"
00005 #include "Core/Matrix/MatCovariance.h"
00006 #include "Core/Matrix/MatInverse.h"
00007 #include "Core/Matrix/MatMul.h"
00008 #include "Core/Array/MulVal.h"
00009 #include "Core/Array/Sub.h"
00010 #include "Core/Array/Add.h"
00011 
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace Tracking
00017 {
00018 
00019 double
00020 Trace(const Array::Array2dScalarReal64* matrix)
00021 {
00022     const double* src = matrix->CPB();
00023     double trace = 0;
00024     int i;
00025     for(i=0 ; i<matrix->CW()*matrix->CH() ; i++)
00026     {
00027         trace += src[i];
00028     }
00029     return trace;
00030 }
00031 
00045 class Classifier
00046 {
00047 public:
00048     Classifier(int size, int dimensionslity)
00049         :mDimensionality(dimensionslity)
00050     {
00051         CmdOptions& options = CmdOptions::GetInstance();
00052         mSize = size;
00053         mGamma = options.GetDouble("fore_back.classifier.gamma", 0.05);
00054         mLambdaFactor = options.GetDouble("fore_back.classifier.lambdafactor", 0.004);
00055         mObjectVectors = new Array::Array2dScalarReal64(mDimensionality, size, 0, 0);
00056         mClassifiers = new Array::Array2dScalarReal64(mDimensionality, size, 0, 0);
00057         mBackgroundMean = new Array::Array2dScalarReal64(mDimensionality, 1, 0, 0);
00058         mMatCovariance = new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00059     }
00060 
00061     virtual ~Classifier()
00062     {
00063         delete mObjectVectors;
00064         delete mClassifiers;
00065         delete mBackgroundMean;
00066         delete mMatCovariance;
00067     }
00068 
00071     void
00072     SetVec(const Array::Array2dScalarReal64& v, int index)
00073     {
00074         if(index >= mSize)
00075             std::cout << "[Classifier::SetVec] Classifier out of bounds" << std::endl;
00076         const double* vp = v.CPB(0,0);
00077         double* op = mObjectVectors->CPB(0,index);
00078         memcpy(op, vp, mDimensionality*sizeof(double));
00079     }
00080 
00084     void
00085     UpdateVec(const Array::Array2dScalarReal64& v, int index)
00086     {
00087         if(index >= mSize)
00088             std::cout << "[Classifier::UpdateVec] Classifier out of bounds" << std::endl;
00089         const double* vp = v.CPB(0,0);
00090         double* op = mObjectVectors->CPB(0,index);
00091         for(int i=0 ; i<mDimensionality ; i++)
00092         {
00093             op[i] = op[i] * (1.0-mGamma) + vp[i] * mGamma;
00094         }
00095     }
00096 
00097     void
00098     GetVector(int index, Array::Array2dScalarReal64& v)
00099     {
00100         double* vp = v.CPB(0, 0);
00101         double* op = mObjectVectors->CPB(0, index);
00102         memcpy(vp, op, mDimensionality*sizeof(double));
00103     }
00104 
00105     void
00106     GetClassifiers(int index, Array::Array2dScalarReal64& v)
00107     {
00108         double* vp = v.CPB(0, 0);
00109         double* op = mClassifiers->CPB(0, index);
00110         memcpy(vp, op, mDimensionality*sizeof(double));
00111     }
00112 
00114     void
00115     SetBackground(Array::Array2dScalarReal64& background)
00116     {
00117         delete mMatCovariance;
00118         mMatCovariance = Matrix::MatCovarianceExact(&background);
00119         MeanFromSamples(mBackgroundMean, &background);
00120         UpdateClassifiers();
00121     }
00122 
00126     void
00127     Update(Array::Array2dScalarReal64& background)
00128     {
00129         UpdateBackGroundModel(background);
00130         UpdateClassifiers();
00131     }
00132 
00133     void
00134     WriteSimpleDebug(std::ostream& stream)
00135     {
00136         stream << "[Classifier::WriteDebug]\n  background";
00137         for(int i=0 ; i<mBackgroundMean->CW() ; i++)
00138             stream << " " << mBackgroundMean->Val(i,0);
00139         stream << "\n  object vectors";
00140         for(int i=0 ; i<mObjectVectors->CH() ; i++)
00141         {
00142             stream << "\n  ";
00143             for(int j=0 ; j<mObjectVectors->CW() ; j++)
00144                 stream << " " << mObjectVectors->Val(i,j);
00145         }
00146     }
00147 
00148     void
00149     WriteDebug(std::ostream& stream)
00150     {
00151         WriteSimpleDebug(stream);
00152         stream << "\n  covariance matrix";
00153         for(int i=0 ; i<mMatCovariance->CH() ; i++)
00154         {
00155             stream << "\n  ";
00156             for(int j=0 ; j<mMatCovariance->CW() ; j++)
00157                 stream << " " << mMatCovariance->Val(i,j);
00158         }
00159         stream << std::endl;
00160     }
00161 
00162 
00163 private:
00164     double mGamma;
00165     double mLambdaFactor;
00166     int mSize;
00167     int mDimensionality;
00168 
00169     Array::Array2dScalarReal64* mMatCovariance;
00170     Array::Array2dScalarReal64* mBackgroundMean;
00171     Array::Array2dScalarReal64* mObjectVectors;
00172     Array::Array2dScalarReal64* mClassifiers;
00173 
00174     void
00175     UpdateBackGroundModel(Array::Array2dScalarReal64& background)
00176     {
00177         // update covariance matrix (eq.19)
00178         Array::Array2dScalarReal64* temp =
00179             new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00180         MulVal(mMatCovariance, mMatCovariance, 1.-mGamma);
00181         MultiplyWithTranspose(temp, mBackgroundMean);
00182         AddMatrixWeighted(mMatCovariance, temp, 1.-mGamma);
00183         // update average fb (eq.18)
00184         MulVal(mBackgroundMean, mBackgroundMean, 1.-mGamma);
00185         Array::Array2dScalarReal64* mean =
00186             new Array::Array2dScalarReal64(mDimensionality, 1, 0, 0);
00187         MeanFromSamples(mean, &background);
00188         AddMatrixWeighted(mBackgroundMean, mean, mGamma);
00189         delete mean;
00190         // continue eq.19
00191         MultiplyWithTranspose(temp, mBackgroundMean);
00192         Sub(mMatCovariance, mMatCovariance, temp);
00193         SommateTransposeMultiplications(temp, &background);
00194         AddMatrixWeighted(mMatCovariance, temp, mGamma);
00195         delete temp;
00196     }
00197 
00198     void
00199     UpdateClassifiers()
00200     {
00201         // update classifiers (eq.13)
00202         // first compute [lambda*I + B]^-1
00203         Array::Array2dScalarReal64* temp =
00204             new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00205         AddLambdaDiagonal(temp, mMatCovariance);
00206         Array::Array2dScalarReal64* Binverse = Matrix::MatInverse(temp);
00207         if(Binverse)
00208         {
00209             for(int i=0 ; i<mObjectVectors->CH() ; i++)
00210             {
00211                 // the term [f_o_i - f_b_avrg] occures multiple times we'll call it vector
00212                 Array::Array2dScalarReal64* vector =
00213                     new Array::Array2dScalarReal64(1, mDimensionality, 0, 0);
00214                 GetNormalisedObjectVector(vector,i);
00215                 // the term [lambda*I + B]^-1 * [f_o_i - f_b_avrg] also
00216                 // reoccures, we'll call it correlatedVector
00217                 Array::Array2dScalarReal64* correlatedVector =
00218                     Matrix::MatMul(Binverse, vector);
00219                 double k_i = CrossProduct(vector, correlatedVector);
00220                 k_i = 2. / (2.+k_i);
00221                 SetClassifier(i, k_i, correlatedVector);
00222                 delete correlatedVector;
00223                 delete vector;
00224             }
00225             delete Binverse;
00226         }
00227         delete temp;
00228     }
00229 
00230 
00232     void
00233     MultiplyWithTranspose(Array::Array2dScalarReal64*& matrix,
00234                           const Array::Array2dScalarReal64* vector)
00235     {
00236         const double* vec = vector->CPB();
00237         MultiplyWithTranspose(matrix, vec);
00238     }
00239 
00241     void
00242     MultiplyWithTranspose(Array::Array2dScalarReal64*& matrix, const double* vec)
00243     {
00244         for(int i=0 ; i<matrix->CH() ; i++)
00245         {
00246             double* dst = matrix->CPB(0, i);
00247             for(int j=0 ; j<matrix->CW() ; j++)
00248                 dst[j] = vec[i]*vec[j];
00249         }
00250     }
00251 
00253     void
00254     AddMatrixWeighted(Array::Array2dScalarReal64*& matrix,
00255                       const Array::Array2dScalarReal64* addmatrix, double weight)
00256     {
00257         double* dst = matrix->CPB();
00258         const double* src = addmatrix->CPB();
00259         for(int i=0 ; i<matrix->CW()*matrix->CH() ; i++)
00260         {
00261             dst[i] += src[i]*weight;
00262         }
00263     }
00264 
00266     void
00267     MeanFromSamples(Array::Array2dScalarReal64*& mean,
00268                     const Array::Array2dScalarReal64* samples)
00269     {
00270         double* dst = mean->CPB();
00271         int i;
00272         for(i=0 ; i<samples->CW() ; i++)
00273             dst[i] = 0;
00274         for(i=0 ; i<samples->CH() ; i++)
00275         {
00276             const double* src = samples->CPB(0, i);
00277             for(int j=0 ; j<samples->CW() ; j++)
00278                 dst[j] += src[j];
00279         }
00280         for(i=0 ; i<samples->CW() ; i++)
00281             dst[i] /= samples->CH();
00282     }
00283 
00285     void
00286     SommateTransposeMultiplications(Array::Array2dScalarReal64*& matrix,
00287                                     const Array::Array2dScalarReal64* samples)
00288     {
00289         double* dst = matrix->CPB();
00290         int i;
00291         for(i=0 ; i<matrix->CW()*matrix->CH() ; i++)
00292             dst[i] = 0;
00293 
00294         Array::Array2dScalarReal64* temp =
00295             new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00296         for(i=0 ; i<samples->CH() ; i++)
00297         {
00298             const double* sample = samples->CPB(0,i);
00299             MultiplyWithTranspose(temp, sample);
00300             Array::Add(matrix, matrix, temp);
00301         }
00302         delete temp;
00303         for(i=0 ; i<matrix->CH()*matrix->CH() ; i++)
00304             dst[i] /= (double)samples->CH();
00305     }
00306 
00307     void
00308     AddLambdaDiagonal(Array::Array2dScalarReal64*& matrixDst,
00309                       const Array::Array2dScalarReal64* matrixSrc)
00310     {
00311         // add portion of trace
00312         double trace = Trace(matrixSrc) * mLambdaFactor;
00313         int i;
00314         for(i=0 ; i<matrixDst->CH() ; i++)
00315         {
00316             double* dst = matrixDst->CPB(0, i);
00317             const double* src = matrixSrc->CPB(0, i);
00318             for(int j=0 ; j<matrixDst->CW() ; j++)
00319             {
00320                 dst[j] = src[j];
00321                 if(i==j)
00322                     dst[j] += trace;
00323             }
00324         }
00325     }
00326 
00327     void
00328     GetNormalisedObjectVector(Array::Array2dScalarReal64*& vector, int index)
00329     {
00330         const double* object = mObjectVectors->CPB(0, index);
00331         const double* backMean = mBackgroundMean->CPB();
00332         double* dst = vector->CPB();
00333         for(int i=0 ; i<mDimensionality ; i++)
00334         {
00335             dst[i] = object[i] - backMean[i];
00336         }
00337     }
00338 
00340     double
00341     CrossProduct(const Array::Array2dScalarReal64* vector1,
00342                  const Array::Array2dScalarReal64* vector2)
00343     {
00344         const double* src1 = vector1->CPB();
00345         const double* src2 = vector1->CPB();
00346         double dst = 0;
00347         for(int i=0 ; i<mDimensionality ; i++)
00348         {
00349             dst += src1[i] * src2[i];
00350         }
00351         return dst;
00352     }
00353 
00354     void
00355     SetClassifier(int index, double k_i,
00356                   const Array::Array2dScalarReal64* correlatedVector)
00357     {
00358         const double* src = correlatedVector->CPB();
00359         double* dst = mClassifiers->CPB(0,index);
00360         for(int i=0 ; i<mDimensionality ; i++)
00361         {
00362             dst[i] = src[i] * k_i;
00363         }
00364     }
00365 
00366 };
00367 
00368 } // namespace Tracking
00369 } // namespace Core
00370 } // namespace Impala
00371 
00372 #endif //Impala_Core_Tracking_Classifier_h

Generated on Thu Jan 13 09:04:39 2011 for ImpalaSrc by  doxygen 1.5.1