Home || Architecture || Video Search || Visual Search || Scripts || Applications || 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 Trace(const Array::Array2dScalarReal64* matrix)
00020 {
00021     // compute trace;
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 
00032 /**************************************************************
00033  * WARNING: this class assumes that all vectors have the same *
00034  *          dimensionality as declared in the constructor.    *
00035  **************************************************************/
00036 class Classifier
00037 {
00038 public:
00039     Classifier(int size, int dimensionslity)
00040         :mDimensionality(dimensionslity)
00041     {
00042         CmdOptions& options = CmdOptions::GetInstance();
00043         mSize = size;
00044         mGamma = options.GetDouble("fore_back.classifier.gamma", 0.05);
00045         mLambdaFactor = options.GetDouble("fore_back.classifier.lambdafactor", 0.004);
00046         mObjectVectors = new Array::Array2dScalarReal64(mDimensionality, size, 0, 0);
00047         mClassifiers = new Array::Array2dScalarReal64(mDimensionality, size, 0, 0);
00048         mBackgroundMean = new Array::Array2dScalarReal64(mDimensionality, 1, 0, 0);
00049         mMatCovariance = new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00050     }
00051 
00052     virtual ~Classifier()
00053     {
00054         delete mObjectVectors;
00055         delete mClassifiers;
00056         delete mBackgroundMean;
00057         delete mMatCovariance;
00058     }
00059     
00060     void SetVec(const Array::Array2dScalarReal64& v, int index)
00061     {
00062         if(index >= mSize)
00063             std::cout << "[Classifier::SetVec] Classifier out of bounds" << std::endl;
00064         const double* vp = v.CPB(0,0);
00065         double* op = mObjectVectors->CPB(0,index);
00066         memcpy(op, vp, mDimensionality*sizeof(double));
00067     }
00068 
00069     void UpdateVec(const Array::Array2dScalarReal64& v, int index)
00070     {
00071         if(index >= mSize)
00072             std::cout << "[Classifier::UpdateVec] Classifier out of bounds" << std::endl;
00073         const double* vp = v.CPB(0,0);
00074         double* op = mObjectVectors->CPB(0,index);
00075         for(int i=0 ; i<mDimensionality ; i++)
00076         {
00077             op[i] = op[i] * (1.0-mGamma) + vp[i] * mGamma;
00078         }
00079     }
00080 
00081     void GetVector(int index, Array::Array2dScalarReal64& v)
00082     {
00083         double* vp = v.CPB(0, 0);
00084         double* op = mObjectVectors->CPB(0, index);
00085         memcpy(vp, op, mDimensionality*sizeof(double));
00086     }
00087 
00088     void GetClassifiers(int index, Array::Array2dScalarReal64& v)
00089     {
00090         double* vp = v.CPB(0, 0);
00091         double* op = mClassifiers->CPB(0, index);
00092         memcpy(vp, op, mDimensionality*sizeof(double));
00093     }
00094 
00095     void SetBackground(Array::Array2dScalarReal64& background)
00096     {
00097         delete mMatCovariance;
00098         mMatCovariance = Matrix::MatCovarianceExact(&background);
00099         MeanFromSamples(mBackgroundMean, &background);
00100         UpdateClassifiers();
00101     }
00102 
00103     void Update(Array::Array2dScalarReal64& background)
00104     {
00105         UpdateBackGroundModel(background);
00106         UpdateClassifiers();
00107     }
00108 
00109     void WriteSimpleDebug(std::ostream& stream)
00110     {
00111         stream << "[Classifier::WriteDebug]\n  background";
00112         for(int i=0 ; i<mBackgroundMean->CW() ; i++)
00113             stream << " " << mBackgroundMean->Val(i,0);
00114         stream << "\n  object vectors";
00115         for(int i=0 ; i<mObjectVectors->CH() ; i++)
00116         {
00117             stream << "\n  ";
00118             for(int j=0 ; j<mObjectVectors->CW() ; j++)
00119                 stream << " " << mObjectVectors->Val(i,j);
00120         }
00121     }
00122 
00123     void WriteDebug(std::ostream& stream)
00124     {
00125         WriteSimpleDebug(stream);
00126         stream << "\n  covariance matrix";
00127         for(int i=0 ; i<mMatCovariance->CH() ; i++)
00128         {
00129             stream << "\n  ";
00130             for(int j=0 ; j<mMatCovariance->CW() ; j++)
00131                 stream << " " << mMatCovariance->Val(i,j);
00132         }
00133         stream << std::endl;
00134     }
00135 
00136 
00137 private:
00138     double mGamma;
00139     double mLambdaFactor;
00140     int mSize;
00141     int mDimensionality;
00142 
00143     Array::Array2dScalarReal64* mMatCovariance;
00144     Array::Array2dScalarReal64* mBackgroundMean;
00145     Array::Array2dScalarReal64* mObjectVectors;
00146     Array::Array2dScalarReal64* mClassifiers;
00147 
00148     void UpdateBackGroundModel(Array::Array2dScalarReal64& background)
00149     {
00150         // update covariance matrix (eq.19)
00151         Array::Array2dScalarReal64* temp = new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00152         MulVal(mMatCovariance, mMatCovariance, 1.-mGamma);
00153         MultiplyWithTranspose(temp, mBackgroundMean);
00154         AddMatrixWeighted(mMatCovariance, temp, 1.-mGamma);
00155         // update average fb (eq.18)
00156         MulVal(mBackgroundMean, mBackgroundMean, 1.-mGamma);
00157         Array::Array2dScalarReal64* mean = new Array::Array2dScalarReal64(mDimensionality, 1, 0, 0);
00158         MeanFromSamples(mean, &background);
00159         AddMatrixWeighted(mBackgroundMean, mean, mGamma);
00160         delete mean;
00161         // continue eq.19
00162         MultiplyWithTranspose(temp, mBackgroundMean);
00163         Sub(mMatCovariance, mMatCovariance, temp);
00164         SommateTransposeMultiplications(temp, &background);
00165         AddMatrixWeighted(mMatCovariance, temp, mGamma);
00166         delete temp;
00167     }
00168 
00169     void UpdateClassifiers()
00170     {
00171         // update classifiers (eq.13)
00172         // first compute [lambda*I + B]^-1
00173         Array::Array2dScalarReal64* temp = new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00174         AddLambdaDiagonal(temp, mMatCovariance);
00175         Array::Array2dScalarReal64* Binverse = Matrix::MatInverse(temp);
00176         if(Binverse)
00177         {
00178             for(int i=0 ; i<mObjectVectors->CH() ; i++)
00179             {
00180                 // the term [f_o_i - f_b_avrg] occures multiple times we'll call it vector
00181                 Array::Array2dScalarReal64* vector = new Array::Array2dScalarReal64(1, mDimensionality, 0, 0);
00182                 GetNormalisedObjectVector(vector,i);
00183                 // the term [lambda*I + B]^-1 * [f_o_i - f_b_avrg] also reoccures, we'll call it correlatedVector
00184                 Array::Array2dScalarReal64* correlatedVector = Matrix::MatMul(Binverse, vector);
00185                 double k_i = CrossProduct(vector, correlatedVector);
00186                 k_i = 2. / (2.+k_i);
00187                 SetClassifier(i, k_i, correlatedVector);
00188                 delete correlatedVector;
00189                 delete vector;
00190             }
00191             delete Binverse;
00192         }
00193         delete temp;
00194     }
00195 
00196 
00197     void MultiplyWithTranspose(Array::Array2dScalarReal64*& matrix, const Array::Array2dScalarReal64* vector)
00198     {
00199         const double* vec = vector->CPB();
00200         MultiplyWithTranspose(matrix, vec);
00201     }
00202 
00203     void MultiplyWithTranspose(Array::Array2dScalarReal64*& matrix, const double* vec)
00204     {
00205         for(int i=0 ; i<matrix->CH() ; i++)
00206         {
00207             double* dst = matrix->CPB(0, i);
00208             for(int j=0 ; j<matrix->CW() ; j++)
00209                 dst[j] = vec[i]*vec[j];
00210         }
00211     }
00212 
00213     void AddMatrixWeighted(Array::Array2dScalarReal64*& matrix, const Array::Array2dScalarReal64* addmatrix, double weight)
00214     {
00215         double* dst = matrix->CPB();
00216         const double* src = addmatrix->CPB();
00217         for(int i=0 ; i<matrix->CW()*matrix->CH() ; i++)
00218         {
00219             dst[i] += src[i]*weight;
00220         }
00221     }
00222 
00223     void MeanFromSamples(Array::Array2dScalarReal64*& mean, const Array::Array2dScalarReal64* samples)
00224     {
00225         double* dst = mean->CPB();
00226         int i;
00227         for(i=0 ; i<samples->CW() ; i++)
00228             dst[i] = 0;
00229         for(i=0 ; i<samples->CH() ; i++)
00230         {
00231             const double* src = samples->CPB(0, i);
00232             for(int j=0 ; j<samples->CW() ; j++)
00233                 dst[j] += src[j];
00234         }
00235         for(i=0 ; i<samples->CW() ; i++)
00236             dst[i] /= samples->CH();
00237     }
00238 
00239     void SommateTransposeMultiplications(Array::Array2dScalarReal64*& matrix, const Array::Array2dScalarReal64* samples)
00240     {
00241         double* dst = matrix->CPB();
00242         int i;
00243         for(i=0 ; i<matrix->CW()*matrix->CH() ; i++)
00244             dst[i] = 0;
00245 
00246         Array::Array2dScalarReal64* temp = new Array::Array2dScalarReal64(mDimensionality, mDimensionality, 0, 0);
00247         for(i=0 ; i<samples->CH() ; i++)
00248         {
00249             const double* sample = samples->CPB(0,i);
00250             MultiplyWithTranspose(temp, sample);
00251             Array::Add(matrix, matrix, temp);
00252         }
00253         delete temp;
00254         for(i=0 ; i<matrix->CH()*matrix->CH() ; i++)
00255             dst[i] /= (double)samples->CH();
00256     }
00257 
00258     void AddLambdaDiagonal(Array::Array2dScalarReal64*& matrixDst, const Array::Array2dScalarReal64* matrixSrc)
00259     {
00260         // add portion of trace
00261         double trace = Trace(matrixSrc) * mLambdaFactor;
00262         int i;
00263         for(i=0 ; i<matrixDst->CH() ; i++)
00264         {
00265             double* dst = matrixDst->CPB(0, i);
00266             const double* src = matrixSrc->CPB(0, i);
00267             for(int j=0 ; j<matrixDst->CW() ; j++)
00268             {
00269                 dst[j] = src[j];
00270                 if(i==j)
00271                     dst[j] += trace;
00272             }
00273         }
00274     }
00275 
00276     void GetNormalisedObjectVector(Array::Array2dScalarReal64*& vector, int index)
00277     {
00278         const double* object = mObjectVectors->CPB(0, index);
00279         const double* backMean = mBackgroundMean->CPB();
00280         double* dst = vector->CPB();
00281         for(int i=0 ; i<mDimensionality ; i++)
00282         {
00283             dst[i] = object[i] - backMean[i];
00284         }
00285     }
00286 
00287     double CrossProduct(const Array::Array2dScalarReal64* vector1, const Array::Array2dScalarReal64* vector2)
00288     {
00289         const double* src1 = vector1->CPB();
00290         const double* src2 = vector1->CPB();
00291         double dst = 0;
00292         for(int i=0 ; i<mDimensionality ; i++)
00293         {
00294             dst += src1[i] * src2[i];
00295         }
00296         return dst;
00297     }
00298 
00299     void SetClassifier(int index, double k_i, const Array::Array2dScalarReal64* correlatedVector)
00300     {
00301         const double* src = correlatedVector->CPB();
00302         double* dst = mClassifiers->CPB(0,index);
00303         for(int i=0 ; i<mDimensionality ; i++)
00304         {
00305             dst[i] = src[i] * k_i;
00306         }
00307     }
00308 
00309 };
00310 
00311 } // namespace Tracking
00312 } // namespace Core
00313 } // namespace Impala
00314 
00315 #endif //Impala_Core_Tracking_Classifier_h

Generated on Fri Mar 19 09:31:21 2010 for ImpalaSrc by  doxygen 1.5.1