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

VisSem.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Feature_VisSem_h
00002 #define Impala_Core_Feature_VisSem_h
00003 
00004 #include "Core/Feature/Computor.h"
00005 #include "Core/Vector/HistogramAccumulation.h"
00006 #include "Core/Vector/Concat.h"
00007 #include "Core/Vector/HistogramIntersection.h"
00008 #include "Core/Vector/Similarity.h"
00009 #include "Core/Vector/HistogramNormalization.h"
00010 #include "Core/Vector/Avg.h"
00011 #include "Core/Vector/Max.h"
00012 #include "Core/Vector/ElemAvg.h"
00013 #include "Core/Vector/ElemMax.h"
00014 #include "Core/Vector/AddAssign.h"
00015 #include "Core/Vector/Clear.h"
00016 #include "Core/Vector/VectorSet.h"
00017 #include "Core/Histogram/MakeHistogram1dSet.h"
00018 #include "Core/Vector/WeibullSim.h"
00019 #include "Core/Histogram/ComputeWeibull.h"
00020 #include "Core/Array/InvWiccest.h"
00021 #include "Core/Array/VisSemGabor.h"
00022 #include "Core/Array/PixStat.h"
00023 
00024 namespace Impala
00025 {
00026 namespace Core
00027 {
00028 namespace Feature
00029 {
00030 
00031 
00032 class VisSem : public Computor
00033 {
00034 public:
00035 
00036     typedef Array::Array2dVec3UInt8 Array2dVec3UInt8;
00037     typedef Array::Array2dScalarReal64 Array2dScalarReal64;
00038     typedef Vector::VectorTem<Real64> VectorReal64;
00039     typedef Array::ArraySet<Array2dScalarReal64> InvSetType;
00040     typedef Histogram::Histogram1dSet<Array2dScalarReal64> HistSetType;
00041 
00042     VisSem(String name, CmdOptions& options) : Computor(name, options)
00043     {
00044         if (GetName() == "vissem")
00045         {
00046             for (int i=0 ; i<options.GetInt("nrScales") ; i++)
00047             {
00048                 String s = "spatialSigma_s" + MakeString(i);
00049                 AddScale(options.GetDouble(s));
00050             }
00051             mDoRot = options.GetBool("doRot");
00052             mDoC = options.GetBool("doC");
00053             mHistBinCount = options.GetInt("histBinCount");
00054             SetRegionDescriptorLength(2); // weibulls
00055         }
00056         if (GetName() == "vissemgabor")
00057         {
00058             mNrOrient = 4;
00059             AddScale(2.828);
00060             mFreq.push_back(0.720);
00061             AddScale(1.414);
00062             mFreq.push_back(2.094);
00063             mHistBinCount = 101;
00064             mCumulativeHist = false;
00065             SetRegionDescriptorLength(mHistBinCount);
00066         }
00067 
00068         mDoCodebook = options.GetBool("doCodebook");
00069         ILOG_INFO("mDoCodebook: " << mDoCodebook);
00070 
00071         // do codeword uncertainty (instead of kernel codebook)
00072         mDoUNC = options.GetBool("doUNC");
00073         ILOG_INFO("doUNC: " << mDoUNC);
00074 
00075         mKeyframesName = FileNameBase(options.GetString("keyframeMask"));
00076         if (mKeyframesName == "")
00077             mKeyframesName = FileNameBase(options.GetString("keyframeMaskAnno"));
00078         if (mKeyframesName == "")
00079             mKeyframesName = "all";
00080 
00081         InvSetType invSet;  // to figure out what is to be computed
00082         ComputePixelFeatureSet(invSet, 0, 0);
00083         SetPixelFeatureSetSize(invSet.Size());
00084 
00085         if (!IsClusterBased())
00086             for (int i=0 ; i<GetNrPixelFeatureSets() ; i++)
00087                 mHistAccu.push_back(NewHistSet());
00088     }
00089 
00090     // add additional information to feature definitions before saving them
00091     virtual FeatureDefinition
00092     ExtendFeatureDefinition(FeatureDefinition def)
00093     {
00094         def = Computor::ExtendFeatureDefinition(def);
00095         def.AddParameter("UNC", mDoUNC);
00096         def.AddParameter("Codebook", mDoCodebook);
00097         return def;
00098     }
00099 
00100     virtual FeatureTable*
00101     MakeProtoFeatureTable(int pixelFeatureSet, int regionFeatureSet,
00102                           String clusterType, String clusterVal)
00103     {
00104         String pName = GetPixelFeatureDefName(pixelFeatureSet);
00105         String pVal = GetPixelFeatureDefVal(pixelFeatureSet);
00106         String rName = GetRegionFeatureDefName(regionFeatureSet);
00107         String rVal = GetRegionFeatureDefVal(regionFeatureSet);
00108         FeatureDefinition def(GetName());
00109         def.AddParameter("proto", FileNameBase(mProtoDataFile));
00110         def.AddParameter("keyframes", mKeyframesName);
00111         def.AddParameter(pName, pVal);
00112         def.AddParameter(rName, rVal);
00113         def.AddParameter(clusterType, clusterVal);
00114         AddProtoFeatureTable(def, 1, GetRegionFeatureLength());
00115         return GetProtoFeatureTableSet()->GetTable(def);
00116     }
00117 
00118     virtual void
00119     ReadPrototypes(String protoSet, String maskSet, int maxNr)
00120     {
00121         ReadProtoFeatureTableSet(protoSet, maskSet);
00122         if (maxNr > 0)
00123             LimitProtoFeatureTableSize(maxNr);
00124         MakeFeatureTableSet();
00125     }
00126 
00127     virtual void
00128     ComputeRegionFeatures(Array::Array2dVec3UInt8* im, Quid quid)
00129     {
00130         HistSetType* hSet = NewHistSet();
00131         for (int p=0 ; p<GetNrPixelFeatureSets() ; p++)
00132         {
00133             InvSetType invSet;
00134             ComputePixelFeatureSet(invSet, p, im);
00135             Array2dScalarReal64* a = invSet.Array(0);
00136             mPyramid.SetImageSize(a->CW(), a->CH());
00137             for (int l=0 ; l<mPyramid.NrLevels() ; l++)
00138             {
00139                 FeatureTable* tab = GetRegionFeatureTable(p, l);
00140                 for (int r=0 ; r<mPyramid.NrRects(l) ; r++)
00141                 {
00142                     Geometry::Rectangle rect = mPyramid.Rect(l, r);
00143                     Histogram::MakeHistogram1dSet(hSet, invSet, rect, true);
00144                     VectorReal64 vec = ComputeRegionDescriptor(hSet);
00145                     if (CheckRegionDescriptor(vec))
00146                         tab->Add(quid, vec);
00147                 }
00148             }
00149             invSet.Delete();
00150         }
00151         delete hSet;
00152     }
00153 
00154     virtual void
00155     ComputeFeatures(Array::Array2dVec3UInt8* im, Quid quid)
00156     {
00157         for (int p=0 ; p<GetNrPixelFeatureSets() ; p++)
00158         {
00159             InvSetType invSet;
00160             ComputePixelFeatureSet(invSet, p, im);
00161             Array2dScalarReal64* a = invSet.Array(0);
00162             mPyramid.SetImageSize(a->CW(), a->CH());
00163             mLazebnikPyramid.SetImageSize(a->CW(), a->CH());
00164             ComputeFeaturesPixelSet(invSet, p, quid);
00165             invSet.Delete();
00166         }
00167     }
00168 
00169     // stat part
00170 
00171     void
00172     InitStat()
00173     {
00174         mFeatMin.reserve(GetPixelFeatureSetSize());
00175         mFeatMax.reserve(GetPixelFeatureSetSize());
00176         mFeatMinAll.reserve(GetPixelFeatureSetSize());
00177         mFeatMaxAll.reserve(GetPixelFeatureSetSize());
00178         for (int i=0 ; i<GetPixelFeatureSetSize() ; i++)
00179         {
00180             mFeatMin[i] = 1000;
00181             mFeatMax[i] = -1000;
00182             mFeatMinAll[i] = 1000;
00183             mFeatMaxAll[i] = -1000;
00184         }
00185     }
00186 
00187     void
00188     ImageStat(Array::Array2dVec3UInt8* im)
00189     {
00190         for (int p=0 ; p<GetNrPixelFeatureSets() ; p++)
00191         {
00192             InvSetType invSet;
00193             ComputePixelFeatureSet(invSet, p, im);
00194 
00195             HistSetType* hSet = NewHistSet();
00196             Geometry::Rectangle roiRect(15, 15, 352-15, 240-15);
00197             Histogram::MakeHistogram1dSet(hSet, invSet, roiRect, true);
00198             for (int i=0 ; i<GetPixelFeatureSetSize() ; i++)
00199             {
00200                 Array2dScalarReal64* roi = MakeRoi(invSet.Array(i), roiRect);
00201                 Real64 minVal, maxVal, meanVal, varVal;
00202                 PixStat(roi, &minVal, &maxVal, &meanVal, &varVal);
00203                 mFeatMin[i] = Min(mFeatMin[i], minVal);
00204                 mFeatMax[i] = Max(mFeatMax[i], maxVal);
00205                 Real64 perc = hSet->Hist(i).OutlierPercentage();
00206                 if (perc > 1)
00207                     std::cout << "maxVal = " << maxVal << ", perc = "
00208                               << perc << ", i = " << i << std::endl;
00209                 delete roi;
00210             }
00211             delete hSet;
00212             invSet.Delete();
00213         }
00214     }
00215 
00216     void
00217     StatMinMax2All()
00218     {
00219         for (int i=0 ; i<GetPixelFeatureSetSize() ; i++)
00220         {
00221             mFeatMinAll[i] = Min(mFeatMin[i], mFeatMinAll[i]);
00222             mFeatMaxAll[i] = Max(mFeatMax[i], mFeatMaxAll[i]);
00223             std::cout << "feat = " << i << ", min = " << mFeatMin[i] << " ("
00224                       << mFeatMinAll[i] << "), max = " << mFeatMax[i]
00225                       << " (" << mFeatMaxAll[i] << ")" << std::endl;
00226             mFeatMin[i] = 1000;
00227             mFeatMax[i] = -1000;
00228         }
00229     }
00230 
00231     // annotation part
00232 
00233     void
00234     ClearAnnoAccu()
00235     {
00236         for (int i=0 ; i<mHistAccu.size() ; i++)
00237             Vector::Clear(mHistAccu[i]);
00238     }
00239 
00240     void
00241     AddImageToAccu(Array::Array2dVec3UInt8* im, Geometry::Rectangle rect)
00242     {
00243         // to match rect.Inside:
00244         //
00245         rect.mLeft += 1;
00246         rect.mRight -= 1;
00247         rect.mTop += 1;
00248         rect.mBottom -= 1;
00249         //
00250 
00251         for (int p=0 ; p<GetNrPixelFeatureSets() ; p++)
00252         {
00253             InvSetType invSet;
00254             ComputePixelFeatureSet(invSet, p, im);
00255             HistSetType* hSet = NewHistSet();
00256             Histogram::MakeHistogram1dSet(hSet, invSet, rect, true);
00257             Vector::AddAssign(mHistAccu[p], hSet, 0, 0, GetPixelFeatureSetSize());
00258             mHistAccu[p]->SetSize(GetPixelFeatureSetSize());
00259             delete hSet;
00260             invSet.Delete();
00261         }
00262     }
00263 
00264     void
00265     AddAccuToAnnoTable(int bookmarkNr, String anno)
00266     {
00267 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00268         Quid quid = mProtoLabels.Add(anno);
00269 #else // REPOSITORY_USED
00270         Quid quid = mProtoLabels->Add(anno);
00271 #endif // REPOSITORY_USED
00272         for (int p=0 ; p<GetNrPixelFeatureSets() ; p++)
00273         {
00274             VectorReal64 v = ComputeRegionDescriptor(mHistAccu[p]);
00275             FeatureTable* tab = GetProtoFeatureTable(p, anno);
00276             tab->Add(quid, v);
00277         }
00278     }
00279 
00280 private:
00281 
00282     HistSetType*
00283     NewHistSet()
00284     {
00285         // default range
00286         HistSetType* hSet = new HistSetType(-1.0, 1.0, mHistBinCount,
00287                                             GetPixelFeatureSetSize());
00288         if (GetName() == "vissemgabor")
00289         {
00290             for (int i=0 ; i<GetPixelFeatureSetSize()-2 ; i++)
00291             { // adjust range for texture
00292                 if (i%3 == 0)
00293                     hSet->SetRange(i, -0.0001, 1.0);
00294                 else
00295                     hSet->SetRange(i, -0.0001, 0.5);
00296             }
00297         }
00298         return hSet;
00299     }
00300 
00301     void
00302     ComputePixelFeatureSet(InvSetType& fSet, int idx, Array2dVec3UInt8* im)
00303     {
00304         if (GetName() == "vissem")
00305             Array::InvWiccest(fSet, im, mDoRot, mDoC, GetScale(idx), 3, true);
00306         if (GetName() == "vissemgabor")
00307             Array::VisSemGabor(fSet, im, GetScale(idx), mFreq[idx], mNrOrient);
00308     }
00309 
00310     VectorReal64
00311     ComputeRegionDescriptor(HistSetType* hSet)
00312     {
00313         if (GetName() == "vissemgabor")
00314         {
00315             if (mCumulativeHist)
00316                 Vector::HistogramAccumulation(hSet, false, true, 0);
00317             else
00318                 Vector::HistogramNormalization(hSet, true, 0);
00319             return Vector::Concat(hSet);
00320         }
00321         // GetName() == "vissem"
00322         VectorReal64 v(GetRegionFeatureLength());
00323         Histogram::ComputeWeibull(v, hSet, false, false);
00324         return v;
00325     }
00326 
00327     bool
00328     CheckRegionDescriptor(VectorReal64 vec)
00329     {
00330         if (GetName() == "vissem")
00331         {
00332             bool eliminateZeros = true;
00333             if (!eliminateZeros)
00334                 return true;
00335             bool ok = true;
00336             for (int i=0 ; i<vec.Size() ; i++)
00337             {
00338                 if (vec[i] == 0)
00339                 {
00340                     ok = false;
00341                     break;
00342                 }
00343             }
00344             return ok;
00345         }
00346         return true;
00347     }
00348 
00349     VectorReal64
00350     ComputeRegionSimilarity(VectorReal64 regionVec, FeatureTable* protoTab)
00351     {
00352         int nrProto = protoTab->Size();
00353         VectorReal64 res(nrProto);
00354         if (GetName() == "vissem")
00355         {
00356             Vector::Similarity(res.GetData(), regionVec, protoTab->GetColumn2(),
00357                                0, 1, Vector::WeibullSim<Real64>);
00358         }
00359         if (GetName() == "vissemgabor")
00360         {
00361             Vector::Similarity(res.GetData(), regionVec, protoTab->GetColumn2(),
00362                                0, 1, Vector::HistogramIntersection<Real64>);
00363             Vector::DivAssign(res, Real64(GetPixelFeatureSetSize()));
00364         }
00365         return res;
00366     }
00367 
00368     // do codeword uncertainty (instead of kernel codebook)
00369     void
00370     DoUNC(FeatureTableSet* regionSim, int regionFeature)
00371     {
00372         for (int r=0 ; r<mPyramid.NrRects(regionFeature) ; r++)
00373         {
00374             Real64 totWeight = 0;
00375             for (int t=0 ; t<regionSim->Size() ; t++)
00376             {
00377                 VectorReal64 regionVec = regionSim->GetTable(t)->Get2(r);
00378                 totWeight += Sum(regionVec);
00379             }
00380             for (int t=0 ; t<regionSim->Size() ; t++)
00381             {
00382                 VectorReal64 regionVec = regionSim->GetTable(t)->Get2(r);
00383                 DivAssign(regionVec, totWeight);
00384                 regionSim->GetTable(t)->Set2(r, regionVec);
00385             }
00386         }
00387     }
00388 
00389     // do the traditional codebook approach (hard assignment)
00390     void
00391     DoCodebook(FeatureTableSet* regionSim, int regionFeature)
00392     {
00393         for (int r=0 ; r<mPyramid.NrRects(regionFeature) ; r++)
00394         {
00395             Real64 maxSim = -1;
00396             for (int t=0 ; t<regionSim->Size() ; t++)
00397             {
00398                 VectorReal64 regionVec = regionSim->GetTable(t)->Get2(r);
00399                 maxSim = Impala::Max(maxSim, ElemMax(regionVec));
00400             }
00401             for (int t=0 ; t<regionSim->Size() ; t++)
00402             {
00403                 VectorReal64 regionVec = regionSim->GetTable(t)->Get2(r);
00404                 for (int i=0 ; i<regionVec.Size() ; i++)
00405                     regionVec[i] = (regionVec[i] == maxSim) ? 1.0 : 0.0;
00406                 regionSim->GetTable(t)->Set2(r, regionVec);
00407             }
00408         }
00409     }
00410 
00411     VectorReal64
00412     DoSpatialPyramid(Geometry::Rectangle rect, VectorReal64 vec)
00413     {
00414         VectorReal64 res(vec.Size() * mLazebnikPyramid.TotalNrRects());
00415         res = 0.0;
00416 
00417         int levelBase = 0;
00418         double normVal = 1.0; // normalization of the pyramid levels
00419         // construct pyramid backwards, to deal with normalization
00420         for (int level=mLazebnikPyramid.NrLevels()-1 ; level>=0 ; level--)
00421         {
00422             // set lazebnik spatial pyramid normalization proportial
00423             // to the number of cells (as Lazebnik does)
00424             if (level != mLazebnikPyramid.NrLevels() - 1)
00425             {
00426                 normVal = normVal / ((double)mLazebnikPyramid.NrRects(level+1) /
00427                                      mLazebnikPyramid.NrRects(level));
00428             }
00429 
00430             int nrRect = mLazebnikPyramid.NrRects(level);
00431             for (int r=0 ; r<nrRect ; r++)
00432             {
00433                 Geometry::Rectangle rectLazeb = mLazebnikPyramid.Rect(level, r);
00434                 // if rect intersects with rectLazebnik, add it to the
00435                 // lazebnikpyramid-bin. This allows putting overlapping
00436                 // regions in multiple lazebnikpyramid-bins.
00437                 if (rectLazeb.Intersects(rect))
00438                 {
00439                     int rectBase = levelBase + r * vec.Size();
00440                     for (int i=0 ; i<vec.Size()  ; i++)
00441                     {
00442                         // do normVal squared, cause later the Vector::Avg is
00443                         // taken, with a lot of zeros which will counterbalance
00444                         // normVal once (leaving one)
00445                         res[rectBase + i] = vec[i] * normVal * normVal;
00446                     }
00447                 }
00448             }
00449             levelBase += nrRect * vec.Size();
00450         }
00451         return res;
00452     }
00453 
00454     void
00455     DoSpatialPyramid(FeatureTableSet* regionSim, int regionFeature,
00456                      FeatureTableSet* regionSimSP)
00457     {
00458         for (int r=0 ; r<mPyramid.NrRects(regionFeature) ; r++)
00459         {
00460             Geometry::Rectangle rect = mPyramid.Rect(regionFeature, r);
00461             for (int t=0 ; t<regionSim->Size() ; t++)
00462             {
00463                 VectorReal64 regionVec = regionSim->GetTable(t)->Get2(r);
00464                 VectorReal64 final = DoSpatialPyramid(rect, regionVec);
00465                 regionSimSP->GetTable(t)->Add(0, final);
00466             }
00467         }
00468     }
00469 
00470     void
00471     ComputeFeaturesPixelSet(InvSetType& invSet, int p, Quid quid)
00472     {
00473         HistSetType* hSet = NewHistSet();
00474         for (int l=0 ; l<mPyramid.NrLevels() ; l++)
00475         {
00476             std::vector<FeatureTable*> protoTabs = GetProtoFeatureTables(p, l);
00477             if (!IsClusterBased())
00478                 protoTabs = GetProtoFeatureTables(p);
00479             FeatureTableSet regionSim;
00480             FeatureTableSet regionSimSP;
00481             for (int t=0 ; t<protoTabs.size() ; t++)
00482             {
00483                 int nrCodeWords = (IsClusterBased()) ? protoTabs[t]->Size() : 1;
00484                 FeatureDefinition def("sim");
00485                 regionSim.Add(new FeatureTable(def, 200, nrCodeWords));
00486                 nrCodeWords *= mLazebnikPyramid.TotalNrRects();
00487                 regionSimSP.Add(new FeatureTable(def, 200, nrCodeWords));
00488             }
00489 
00490             for (int r=0 ; r<mPyramid.NrRects(l) ; r++)
00491             {
00492                 Geometry::Rectangle rect = mPyramid.Rect(l, r);
00493                 Histogram::MakeHistogram1dSet(hSet, invSet, rect, true);
00494 
00495                 VectorReal64 exVec = ComputeRegionDescriptor(hSet);
00496 
00497                 for (int t=0 ; t<protoTabs.size() ; t++)
00498                 {
00499                     VectorReal64 sVec = ComputeRegionSimilarity(exVec,
00500                                                                 protoTabs[t]);
00501                     VectorReal64 regionVec;
00502                     if (IsClusterBased())
00503                     {
00504                         regionVec = sVec;
00505                     }
00506                     else
00507                     {   // average all annos (kernel codebook)
00508                         regionVec = VectorReal64(1);
00509                         regionVec[0] = Vector::ElemAvg(sVec, 0, 0, -1);
00510                     }
00511                     regionSim.GetTable(t)->Add(0, regionVec);
00512                 }
00513             }
00514 
00515             if (mDoUNC)
00516                 DoUNC(&regionSim, l);
00517             if (mDoCodebook)
00518                 DoCodebook(&regionSim, l);
00519             DoSpatialPyramid(&regionSim, l, &regionSimSP);
00520 
00521             for (int t=0 ; t<protoTabs.size() ; t++)
00522             {
00523                 FeatureTable* simTab = regionSimSP.GetTable(t);
00524                 VectorReal64 vMax;
00525                 Vector::Max(&vMax, simTab->GetColumn2(), simTab->Size(), 0);
00526 
00527                 VectorReal64 vAvg;
00528                 Vector::Avg(&vAvg, simTab->GetColumn2(), simTab->Size(), 0);
00529                 FeatureDefinition def = protoTabs[t]->GetFeatureDefinition();
00530                 FeatureTable* tab = GetFeatureTable(def, l);
00531                 tab->Add(quid, Vector::Concat(vMax, vAvg));
00532             }
00533             regionSim.Delete();
00534             regionSimSP.Delete();
00535         }
00536         delete hSet;
00537     }
00538 
00539     bool                mDoRot;
00540     bool                mDoC;
00541     int                 mHistBinCount;
00542     bool                mCumulativeHist;
00543     int                 mNrOrient;
00544     std::vector<double> mFreq;
00545 
00546     std::vector<Real64> mFeatMin;
00547     std::vector<Real64> mFeatMax;
00548     std::vector<Real64> mFeatMinAll;
00549     std::vector<Real64> mFeatMaxAll;
00550 
00551     std::vector<HistSetType*> mHistAccu;
00552 
00553     String mKeyframesName;
00554     bool   mDoCodebook;
00555     bool   mDoUNC;
00556 
00557     ILOG_VAR_DEC;
00558 };
00559 
00560 ILOG_VAR_INIT(VisSem, Impala.Core.Feature);
00561 
00562 } // namespace Feature
00563 } // namespace Core
00564 } // namespace Impala
00565 
00566 #endif

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