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
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
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
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;
00117 bestPoint = j;
00118 }
00119 }
00120 std::cout << maxSim << dot << std::flush;
00121 if (maxSim < 2)
00122 {
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
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
00152
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
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
00184 if (isCandidate)
00185 mBuffer->Add(quid, vec);
00186
00187
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
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
00230 int max = -1;
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
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;
00307 bool mAllowSlack;
00308 Real64 mSlack;
00309 int mSlackStart;
00310 int mNrSamplesAtime;
00311 int mNrConsidered;
00312 bool mCanProcess;
00313 int mProcessEnded;
00314
00315 FeatureTable* mClusterVec;
00316 std::vector<int> mClusterCount;
00317
00318 FeatureTable* mBuffer;
00319
00320 SimFunc mSimFunc;
00321
00322 };
00323
00324 }
00325 }
00326 }
00327
00328 #endif