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

RadiusClusteror.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Feature_RadiusClusteror_h
00002 #define Impala_Core_Feature_RadiusClusteror_h
00003 
00004 #include <vector>
00005 #include "Core/Feature/Clusteror.h"
00006 #include "Core/Vector/MinimumSimilarity.h"
00007 #include "Core/Vector/AverageSimilarity.h"
00008 #include "Core/Vector/RadiusSimilarity.h"
00009 #include "Core/Table/RemoveRow.h"
00010 
00011 namespace Impala
00012 {
00013 namespace Core
00014 {
00015 namespace Feature
00016 {
00017 
00018 
00021 template <class SimFunc>
00022 class RadiusClusteror : public Clusteror
00023 {
00024 public:
00025 
00026     typedef Core::Vector::VectorTem<Real64> VectorReal64;
00027 
00028     static const int MODE_ORG = 1;
00029     static const int MODE_NEW = 2;
00030     static const int MODE_COUNT = 3;
00031 
00032     RadiusClusteror(int pixelFeatureSet, int regionFeatureSet, Real64 radius,
00033                     int nrSamplesAtime, int nrWantedClusters,
00034                     int minElemsInCluster, SimFunc simFunc) :
00035         Clusteror(pixelFeatureSet, regionFeatureSet, nrWantedClusters,
00036                   minElemsInCluster)
00037     {
00038         mMode = MODE_COUNT;
00039         mRadius = radius;
00040         mAllowOverlap = true;
00041         mAllowSlack = false;
00042         mSlack = 1.0;
00043         mSlackStart = -1;
00044         mNrSamplesAtime = nrSamplesAtime;
00045         mNrConsidered = 0;
00046         mCanProcess = true;
00047         mProcessEnded = -1;
00048         mSimFunc = simFunc;
00049 
00050         mClusterVec = 0;
00051         mBuffer = 0;
00052     }
00053 
00054     virtual String
00055     GetClusterType() const
00056     {
00057         return "radius";
00058     }
00059 
00060     virtual String
00061     GetClusterVal() const
00062     {
00063         return MakeString(mRadius);
00064     }
00065 
00066     virtual void
00067     InitClusterVec(FeatureTable* clusters, String mode, int val)
00068     {
00069         CheckFeatureLen(clusters->GetFeatureVectorLength());
00070         for (int i=0 ; i<clusters->Size() ; i++)
00071         {
00072             mClusterVec->Add(clusters->Get1(i), clusters->Get2(i));
00073             mClusterCount.push_back(0);
00074         }
00075         PrintStatus();
00076     }
00077 
00078     virtual void
00079     ProcessBuffer()
00080     {
00081         ILOG_VAR(Impala.Core.Feature.RadiusClusteror.ProcessBuffer);
00082         if (!mCanProcess)
00083         {
00084             ILOG_ERROR("cannot process, do not call");
00085             return;
00086         }
00087 
00088         String dot = (GetRegionFeatureSet() == 0) ? ":" : ".";
00089         std::cout << dot << std::flush;
00090 
00091         // find the 'best' point for a new cluster
00092         int bestPoint = -1;
00093         Real64 maxSim = -1;
00094         for (int j=0 ; j<mBuffer->Size() ; j++)
00095         {
00096             VectorReal64 vec = mBuffer->Get2(j);
00097             /*
00098             Real64 sim;
00099             if (mMode == MODE_ORG)
00100                 sim = Vector::MinimumSimilarity(vec, mBuffer->GetColumn2(),
00101                                                 mBuffer->Size(), mSimFunc);
00102             if (mMode == MODE_NEW)
00103                 sim = Vector::AverageSimilarity(vec, mBuffer->GetColumn2(),
00104                                                 mBuffer->Size(), mSimFunc);
00105             if (mMode == MODE_COUNT)
00106                 sim = Vector::RadiusSimilarity(vec, mBuffer->GetColumn2(),
00107                                                mRadius, mBuffer->Size(),
00108                                                mSimFunc);
00109             */
00110             Real64 sim = Vector::RadiusSimilarity(vec, mBuffer->GetColumn2(),
00111                                                   mRadius / mSlack,
00112                                                   mBuffer->Size(), mSimFunc);
00113 
00114             if (sim > maxSim)
00115             {
00116                 maxSim = sim;  // keep the point with the largest sim
00117                 bestPoint = j;
00118             }
00119         }
00120         std::cout << maxSim << dot << std::flush;
00121         if (maxSim < 2)
00122         {   // no sensible candidate found in current buffer
00123             if (mAllowSlack && (mSlack < 2))
00124             {
00125                 mSlack *= 2;
00126                 mSlackStart = mNrConsidered;
00127                 return ProcessBuffer();
00128             }
00129             mCanProcess = false;
00130             mProcessEnded = mNrConsidered;
00131             return;
00132         }
00133 
00134         mClusterVec->Add(mBuffer->Get1(bestPoint), mBuffer->Get2(bestPoint));
00135 
00136         // remove points within range of the new cluster
00137         bool* filter = new bool[mBuffer->Size()];
00138         VectorReal64 bestVec = mBuffer->Get2(bestPoint);
00139         int count = 0;
00140         maxSim = -1;
00141         Real64 radThres = mRadius * ((mAllowOverlap) ? 1.0 : 0.5);
00142         for (int i=0 ; i<mBuffer->Size() ; i++)
00143         {
00144             Real64 sim = mSimFunc.DoIt(bestVec, mBuffer->Get2(i));
00145             filter[i] = (sim >= radThres);
00146             if (sim >= mRadius)
00147                 count++;
00148             if (sim > maxSim)
00149                 maxSim = sim;
00150         }
00151         //if (count == 0)
00152         //    ILOG_INFO("Similarity too high: max = " << maxSim);
00153         Table::RemoveRow(mBuffer, filter);
00154         delete filter;
00155 
00156         mClusterCount.push_back(count);
00157     }
00158 
00159     void
00160     Cluster(VectorReal64 vec, Quid quid)
00161     {
00162         CheckFeatureLen(vec.Size());
00163         mNrConsidered++;
00164 
00165         // check if a new point is a candidate for a new cluster
00166         bool isCandidate = true;
00167         int i = 0;
00168         Real64 radThres = mRadius * ((mAllowOverlap) ? 1.0 : 0.5);
00169         while (isCandidate && i<mClusterVec->Size())
00170         {
00171             Real64 sim = mSimFunc.DoIt(mClusterVec->Get2(i), vec);
00172             if (sim >= radThres)
00173             {
00174                 isCandidate = false;
00175                 if (sim >= mRadius)
00176                     mClusterCount[i]++;
00177             }
00178             i++;
00179         }
00180         if (!mCanProcess || HadEnough())
00181             return;
00182 
00183         // if point is a candidate, add the point to the todo list
00184         if (isCandidate)
00185             mBuffer->Add(quid, vec);
00186 
00187         // if buffer large enough, process it
00188         while ((mBuffer->Size() > mNrSamplesAtime)
00189                && mCanProcess && (!HadEnough()))
00190         {
00191             ProcessBuffer();
00192         }
00193     }
00194 
00195     virtual void
00196     Cluster(FeatureTable* tab)
00197     {
00198         for (int i=0 ; i<tab->Size() ; i++)
00199             Cluster(tab->Get2(i), tab->Get1(i));
00200     }
00201 
00202     virtual bool
00203     HadEnough()
00204     {
00205         //return CountClusters() >= mNrWantedClusters;
00206         return mClusterVec->Size() >= mNrWantedClusters;
00207     }
00208 
00209     virtual void
00210     FinishBuffer()
00211     {
00212         PrintStatus();
00213         while ((!IsBufferEmpty()) && mCanProcess && (!HadEnough()))
00214         {
00215             ProcessBuffer();
00216         }
00217         PrintStatus();
00218     }
00219 
00220     virtual void
00221     Clusters2FeatureTable(FeatureTable* table)
00222     {
00223         PrintStatus();
00224 
00225         bool done = false;
00226         while (!done)
00227         {
00228             int idx = -1;
00229             //int max = mMinElemsInCluster; // discard clusters with less elems
00230             int max = -1; // export all clusters
00231             for (int i=0 ; i<mClusterVec->Size() ; i++)
00232             {
00233                 if (mClusterCount[i] > max)
00234                 {
00235                     max = mClusterCount[i];
00236                     idx = i;
00237                 }
00238             }
00239             if (idx != -1)
00240             {
00241                 table->Add(mClusterVec->Get1(idx), mClusterVec->Get2(idx));
00242                 mClusterCount[idx] = -1;
00243             }
00244             else
00245             {
00246                 done = true;
00247             }
00248         }
00249     }
00250 
00251     virtual void
00252     PrintStatus()
00253     {
00254         int cov = 0;
00255         int covOK = 0;
00256         for (int i=0 ; i<mClusterCount.size() ; i++)
00257         {
00258             cov += mClusterCount[i];
00259             if (mClusterCount[i] >= mMinElemsInCluster)
00260                 covOK += mClusterCount[i];
00261         }
00262 
00263         std::cout << "Clusteror: " << " clusters=" << mClusterVec->Size()
00264                   << ", ok=" << CountClusters() << ", covered " << cov << "/"
00265                   << covOK << " of " << mNrConsidered
00266                   << "  - " << mPixelFeatureSet
00267                   << "," << mRegionFeatureSet << " - r=" << mRadius << " ("
00268                   << mRadius / mSlack << "/" << mSlackStart << ")"
00269                   << " ended=" << mProcessEnded << std::endl;
00270     }
00271 
00272 private:
00273 
00274     void
00275     CheckFeatureLen(int vecLen)
00276     {
00277         if (!mBuffer)
00278         {
00279             mClusterVec = new FeatureTable(FeatureDefinition("clusters"),
00280                                            100, vecLen);
00281             mBuffer = new FeatureTable(FeatureDefinition("buf"),
00282                                        mNrSamplesAtime, vecLen);
00283         }
00284     }
00285 
00286     // the nr. of clusters for which holds: #elems > mMinElemsInCluster
00287     int
00288     CountClusters()
00289     {
00290         int nrClusters = 0;
00291         for (int i=0 ; i<mClusterCount.size() ; i++)
00292             if (mClusterCount[i] >= mMinElemsInCluster)
00293                 nrClusters++;
00294         return nrClusters;
00295     }
00296 
00297     bool
00298     IsBufferEmpty()
00299     {
00300         return (mBuffer->Size() == 0);
00301     }
00302 
00303 
00304     int    mMode;
00305     Real64 mRadius;
00306     bool   mAllowOverlap;   // indicates clusters should be 1 or 2 radius apart
00307     bool   mAllowSlack;     // are we allowed to decrease radius
00308     Real64 mSlack;
00309     int    mSlackStart;     // nr considered when adding slack
00310     int    mNrSamplesAtime; // threshold to start processing buffer
00311     int    mNrConsidered;   // total nr of points considered for clustering
00312     bool   mCanProcess;     // does it make sense to consider more features?
00313     int    mProcessEnded;   // nr considered when stopped processing
00314 
00315     FeatureTable*    mClusterVec;   // the clusters (representative vectors)
00316     std::vector<int> mClusterCount; // nr. of points belonging to each cluster
00317 
00318     FeatureTable* mBuffer; // list of vectors still to be assigned to a cluster
00319 
00320     SimFunc mSimFunc;
00321 
00322 };
00323 
00324 } // namespace Feature
00325 } // namespace Core
00326 } // namespace Impala
00327 
00328 #endif

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