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

ShotSegmenter.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_VideoSet_ShotSegmenter_h
00002 #define Impala_Core_VideoSet_ShotSegmenter_h
00003 
00004 #include "Persistency/SimilarityTableSetRepository.h"
00005 #include "Core/Stream/RgbDataSrc.h"
00006 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00007 #include "Core/Training/Svm.h"
00008 #endif // REPOSITORY_USED
00009 #include "Core/Histogram/Histogram1dTem.h"
00010 #include "Core/Histogram/MakeHistogram1d.h"
00011 #include "Core/Array/SetVal.h"
00012 #include "Core/Array/PixMin.h"
00013 #include "Core/Array/PixMax.h"
00014 #include "Core/Array/MulVal.h"
00015 #include "Core/Array/AddVal.h"
00016 #include "Core/Array/PixSum.h"
00017 #include "Core/Array/Sqrt.h"
00018 #include "Core/Array/Minimum.h"
00019 #include "Core/Array/Maximum.h"
00020 #include "Core/Array/Statistics.h"
00021 #include "Core/Array/LessThanVal.h"
00022 #include "Core/Array/ProjectRange.h"
00023 #include "Core/Array/MakeGaussian1d.h"
00024 #include "Core/Array/RGB2Intensity.h"
00025 #include "Core/Array/ColorSpace.h"
00026 #include "Core/Array/ArraySystem.h"
00027 #include "Core/Array/RecGauss.h"
00028 
00029 #include "Core/Vector/HistogramIntersection.h"
00030 #include "Core/Vector/KullbackDivergence.h"
00031 
00032 #include "Core/VideoSet/Reporter.h"
00033 #include "Core/VideoSet/Listener.h"
00034 #include "Core/VideoSet/Mpeg7DocWrite.h"
00035 #include "Core/Table/SimilarityTableSet.h"
00036 #include "Persistency/XmlFileReader.h"
00037 
00038 #include "Core/Geometry/RectanglePyramid.h"
00039 #include "Basis/FileExists.h"
00040 #include "Core/Vector/ElemMin.h"
00041 
00042 namespace Impala
00043 {
00044 namespace Core
00045 {
00046 namespace VideoSet
00047 {
00048 
00049 
00050 class ShotSegmenter : public Listener
00051 {
00052 public:
00053 
00054     typedef Core::Histogram::Histogram1dTem<Real64> HistType;
00055     typedef Array::Array2dScalarReal64 ArrayType;
00056     typedef Array::Array2dScalarReal64 Array2dScalarReal64;
00057 
00058     ShotSegmenter(Reporter* reporter,CmdOptions& options)
00059     {
00060         //Walk Listener setup////////////////////
00061         mReporter = reporter;
00062         
00063         mScores=0;
00064         mPredictions=0;
00065         mFeatures=0;
00066         mFeaturesReversed=0;
00067         mHistograms=0;
00068         
00069         //Similarity Types
00070         mSim         = options.GetString ("SSSim","+");
00071         mHistSim     = options.GetString ("SSHistSim","Intersection");
00072         mSymmetry    = options.GetString ("SSSymmetry","None");
00073 
00074         //Preprocessing
00075         mHistEq      = options.GetBool   ("SSHistEq",false);
00076         mHistNorm    = options.GetBool   ("SSHistNorm",true);
00077         mBlur        = options.GetBool   ("SSBlur",true);
00078         mBlurDer     = options.GetBool   ("SSBlurDer",0);
00079         mBlurSigma   = options.GetDouble ("SSBlurSigma",1.);
00080         mNormW       = options.GetBool   ("SSNormW",false);
00081 
00082         //GPM Parameters///////////////////////////////////////
00083         mThreshold   = options.GetDouble ("SSThreshold",3.4);
00084         mRadius      = options.GetInt    ("SSRadius",6);
00085         mSigma       = options.GetDouble ("SSSigma",18);
00086         mBinCount    = options.GetInt    ("SSBinCount",32);
00087         mCentered    = options.GetBool   ("SSCentered",false);
00088         mPyrL        = options.GetInt    ("SSPyrL",1);
00089         mPyrU        = options.GetInt    ("SSPyrU",2);
00090         mProbThresh  = options.GetDouble ("SSProbThresh",0.5);
00091         mShortGrad   = options.GetInt    ("SSShortGrad",3); //Anything
00092 
00093         //RunModes/////////////////////////////////////////////
00094         mMode         = options.GetString ("SSMode","Run");          //Test,Train,EvalTrain,EvalTest,Run
00095         mRunName      = options.GetString ("SSRunName","NoRunName"); //Anything
00096         mGUI          = options.GetBool   ("SSGUI",false);
00097         mThresholdOnly= options.GetBool   ("SSThresholdOnly",false);
00098         mPredictOnly  = options.GetBool   ("SSPredictOnly",false);
00099         mPredictOutput= options.GetBool   ("SSPredictOutput",false);
00100         mDoProcessing = options.GetBool   ("SSDoProcessing",true);
00101         mDoProcessing = mDoProcessing&&(!(mThresholdOnly||mPredictOnly));
00102         
00103         //Directories//////////////////////////////////////////
00104         mDataDir      = options.GetString ("data");
00105         mRefDir       = options.GetString ("SSRefDir");
00106         if(mRefDir==""){
00107             mRefDir=mDataDir+"/ShotSegmentation/ref";
00108         }
00109         
00110         //Other
00111         mRefPrefix   = options.GetString ("SSRefPrefix","/ref_");
00112         mSvmModelFile= options.GetString ("SSModelFile","default");
00113         mVerbose     = options.GetInt   ("SSVerbose",0);
00114         
00115         mWindowSize  = mCentered ? 2 * mRadius + 1 : 2 * mRadius;
00116 
00117         ILOG_INFO("Shot Segmentation Parameters:");
00118         ILOG_INFO("---------------------------------");
00119         ILOG_INFO("  Radius    :"<<mRadius);
00120         ILOG_INFO("  Sigma     :"<<mSigma);
00121         ILOG_INFO("  BinCount  :"<<mBinCount);
00122         ILOG_INFO("  Threshold :"<<mThreshold);
00123         ILOG_INFO("  HistEq    :"<<(mHistEq ? "yes" : "no"));
00124         ILOG_INFO("  HistNorm  :"<<(mHistNorm ? "yes" : "no"));
00125         ILOG_INFO("  Sim       :"<<mSim);
00126         ILOG_INFO("  HistSim   :"<<mHistSim);
00127         ILOG_INFO("  Symmetry  :"<<mSymmetry);
00128         ILOG_INFO("  Centered  :"<<(mCentered?"yes":"no"));
00129         ILOG_INFO("  Blur      :"<<(mBlur?"yes":"no"));
00130         ILOG_INFO("  BlurDer   :"<<mBlurDer);
00131         ILOG_INFO("  BlurSigma :"<<mBlurSigma);
00132         ILOG_INFO("  mNormW    :"<<(mNormW?"yes":"no"));
00133         ILOG_INFO("  ProbThresh:"<<mProbThresh);
00134         ILOG_INFO("  ShortGrad :"<<mShortGrad);
00135         ILOG_INFO("  Pyr. Lower:"<<mPyrL);
00136         ILOG_INFO("  Pyr. Upper:"<<mPyrU);
00137         ILOG_INFO("");
00138         ILOG_INFO("Shot Segmentation Modes:");
00139         ILOG_INFO("---------------------------------");
00140         ILOG_INFO("  Mode      :"<<mMode);
00141         ILOG_INFO("  GUI       :"<<(mGUI ? "yes" : "no"));
00142         ILOG_INFO("  RunName   :"<<mRunName);
00143         ILOG_INFO("  ThreshOnly:"<<(mThresholdOnly?"yes":"no"));
00144         ILOG_INFO("  PredctOnly:"<<(mPredictOnly?"yes":"no"));
00145         ILOG_INFO("  PredctOut :"<<(mPredictOutput?"yes":"no"));
00146         ILOG_INFO("  Processing:"<<(mDoProcessing?"yes":"no"));
00147         ILOG_INFO("");
00148         ILOG_INFO("Shot Segmentation Directories:");
00149         ILOG_INFO("---------------------------------");
00150         ILOG_INFO("  Data      :"<<mDataDir);
00151         ILOG_INFO("  Ref       :"<<mRefDir);
00152         ILOG_INFO("  ModelFile :"<<mSvmModelFile);
00153             
00154         mPyramid=Geometry::RectanglePyramid(0,mPyrL,mPyrU,1,-1,-1);
00155 
00156         ILOG_INFO("Pyramid has "<< mPyramid.TotalNrRects()<<" rectangles.");
00157         mHistPerFrame = 3 * mPyramid.TotalNrRects();
00158 
00159 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00160         if(((mMode=="Run")||(mPredictOnly))&&(mSvmModelFile==""))
00161         {
00162             ILOG_INFO("You should supply a model file for prediction!");
00163             ILOG_INFO("Prediction will not be possible!");
00164             return;
00165         }
00166         else if((mMode=="Run")||(mPredictOnly))
00167         {
00168             mSvm=new Core::Training::Svm;
00169             
00170             Util::Database& Db = Util::Database::GetInstance();
00171             String FileName=Db.GetFilePath("ShotSegmentation","Models",mRunName,mSvmModelFile,false,true);
00172             if (FileName!=""){
00173                 ILOG_INFO("Loading Model");
00174                 mSvm->LoadModel(FileName, &Db);
00175                 ILOG_INFO("Loaded Model");
00176             }else{
00177                 delete mSvm;
00178                 mSvm=0;
00179                 ILOG_INFO("SVM file not opened");
00180             }
00181             //TODO:get the SS parameters from the file name
00182             //standardize file names
00183         }else{
00184             ILOG_INFO("No SVM");
00185             mSvm=0;
00186         }
00187 #else // REPOSITORY_USED
00188         ILOG_INFO("No SVM");
00189 #endif // REPOSITORY_USED
00190         
00191         //Prepare the 1-d gaussian filter to be used for scaling in time
00192         mGauss = Array::MakeGaussian1d(mSigma,0,0,mWindowSize*2+1,mWindowSize*2+1);
00193         
00194     }
00195 
00196     virtual
00197     ~ShotSegmenter()
00198     {
00199 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00200         if(mSvm)
00201             delete mSvm;
00202 #endif // REPOSITORY_USED
00203         //Clean the walk listener pointers
00204         if(mScores)
00205             delete mScores;
00206         if(mPredictions)
00207             delete mPredictions;
00208         if(mHistograms){
00209             for(int i=0;i<mWindowSize*mHistPerFrame;i++)
00210             {   
00211                delete mHistograms[i];
00212             }
00213             delete[] mHistograms;
00214         }
00215         if(mFeatures)
00216             delete mFeatures;
00217         if(mFeaturesReversed)
00218             delete mFeaturesReversed;
00219     }
00220 
00221     void
00222     HandleNewFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00223     {
00224         mSrc=src;
00225         mShotNr=0;
00226         //Allocate the arrays for the next file
00227         mWeights = Array::ArrayCreate<Array2dScalarReal64>(mWindowSize,mWindowSize);
00228         SetVal(mWeights,0);
00229 
00230         if (src->LastFrame() < 0)
00231         {
00232             ILOG_ERROR("[HandleNewFile] src->LastFrame() = " << src->LastFrame()
00233                        << " (fileId = " << fileId << ")");
00234             exit(-1);
00235         }
00236 
00237         int lastFrame = src->LastFrame();
00238         mPredictions = Array::ArrayCreate<Array2dScalarReal64>(lastFrame,1,0,0);
00239         SetVal(mPredictions,0);
00240 
00241         mScores = Array::ArrayCreate<Array2dScalarReal64>(src->LastFrame(),1,0,0);
00242         SetVal(mScores,0);
00243 
00244         mFeatures=new Vector::VectorTem<Real64>(mCentered?mWindowSize+1:mWindowSize);
00245         mFeaturesReversed=new Vector::VectorTem<Real64>(mCentered?mWindowSize+1:mWindowSize);
00246         mHistograms = new HistType*[mWindowSize*mHistPerFrame];
00247         for(int i=0;i<mWindowSize*mHistPerFrame;i++)
00248         {
00249             mHistograms[i]=new HistType(0, 256, mBinCount, 0);
00250         }
00251         
00252         mGroundTruth= Array::ArrayCreate<Array2dScalarReal64>(mSrc->LastFrame(),4,0,0);
00253         mCUTs= Array::ArrayCreate<Array2dScalarReal64>(mSrc->LastFrame(),1,0,0);
00254         mDISs= Array::ArrayCreate<Array2dScalarReal64>(mSrc->LastFrame(),1,0,0);
00255         mOTHs= Array::ArrayCreate<Array2dScalarReal64>(mSrc->LastFrame(),1,0,0);
00256         mFOIs= Array::ArrayCreate<Array2dScalarReal64>(mSrc->LastFrame(),1,0,0);
00257 
00258         Array::SetVal(mGroundTruth,0);
00259         Array::SetVal(mCUTs,0);
00260         Array::SetVal(mDISs,0);
00261         Array::SetVal(mOTHs,0);
00262         Array::SetVal(mFOIs,0);
00263         
00264         mPyramid.SetImageSize(mSrc->FrameWidth(),mSrc->FrameHeight());
00265      
00266         //if((mMode=="Train")||(mMode=="Test")||(mMode=="EvalTrain")||(mMode=="EvalTest"))
00267         ReadGroundTruth();
00268 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00269         if(!mDoProcessing){
00270             char OutFileName[300];
00271             Util::Database D;
00272             String SrcName = mSrc->GetName();
00273             SrcName=Impala::FileNameBase(SrcName);
00274 
00275             //Scores File
00276             sprintf(OutFileName,"%s_%d-%g-%d.txt",SrcName.c_str(),
00277                                         mRadius,mSigma,mBinCount);
00278             Util::Database& Db = Util::Database::GetInstance();
00279             String FileName=Db.GetFilePath("ShotSegmentation","Scores",mMode,mRunName,OutFileName,false,false);
00280             Util::IOBuffer* Input=Db.GetIOBuffer(FileName,true,false,"tmp");
00281             if(Input && Input->Valid())
00282             {
00283                 ILOG_INFO("No Processing will be done,");
00284                 ILOG_INFO("Reading Scores from "<<FileName);
00285                 int frame;
00286                 double score;
00287                 std::strstream oss;
00288                 for (int i=0;i<mScores->CW();i++){
00289                     oss<<Input->ReadLine();
00290                     oss>>frame;
00291                     oss>>score;
00292                     //Output->ReadNativeTypeRead(&frame);
00293                     //Output->ReadNativeTypeRead(&score);
00294                     mScores->SetValue(score,frame,0);
00295                 }
00296             }else
00297                 mDoProcessing=true;
00298         }
00299 #endif // REPOSITORY_USED
00300     }
00301 
00302     void
00303     HandleNewFrame(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00304     {       
00305         int ProcessFrame=mSrc->FrameNr();
00306         int ScoreFrame=ProcessFrame-mRadius;
00307         int PredictFrame=GetPredictionFrame();
00308 
00309         if (mDoProcessing)
00310         {
00311             UpdateHistograms(mSrc->DataPtr());
00312 
00313             if (ProcessFrame>=mWindowSize-1)
00314             {
00315                 ComputeSSWeights();
00316                 Real64 score=CalculateScores();
00317                 mScores->SetValue(score,ScoreFrame,0);
00318             }
00319         }
00320         
00321         Predict(PredictFrame);
00322         
00323         if ((mMode=="Train") || (mMode=="Test") || (mMode=="EvalTrain") ||
00324             (mMode=="EvalTest"))
00325         {
00326             return;
00327         }
00328     
00329         if (mGUI && (ProcessFrame==mSrc->LastFrame()))
00330         {
00331             HandleDoneFile(vs, fileId, src);
00332         }
00333     }
00334 
00335     void
00336     WritePredictions()
00337     {
00339         //TRECVID Evaluation output
00340 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00341         ILOG_INFO("Writing Predictions");
00342         String SrcName = mSrc->GetName();
00343         SrcName=Impala::FileNameBase(SrcName);
00344 
00345         char OutFileName[300];
00346         sprintf(OutFileName,"%s_%d-%g-%d.xml",SrcName.c_str(),
00347                                     mRadius,mSigma,mBinCount);
00348         Util::Database& Db = Util::Database::GetInstance();
00349         Db.MakeDir("ShotSegmentation","Predict",mRunName);
00350         String FileName=Db.GetFilePath("ShotSegmentation","Predict",mRunName,OutFileName,true,false);
00351         Util::IOBuffer* Output=Db.GetIOBuffer(FileName,false,false,"tmp");
00352         if(Output && Output->Valid())
00353         {
00354             ILOG_INFO("Writing Results to "<<FileName);
00355             Output->Puts(" <seg src=\""+SrcName+".mpg\">\n");
00356             int start=0;
00357             int cut;
00358             std::ostringstream oss;
00359 
00360             for (int i=mRadius+1;i<mPredictions->CW();i++){
00361                 
00362                 if(mPredictions->Value(i,0)>=mProbThresh){
00363                     start=i;
00364                     while(mPredictions->Value(i,0)>=mProbThresh)
00365                         i++;
00366 //                        if(i-start<6)
00367 //                            continue;
00368                     cut=(start+i)/2;
00369                     oss<<"  <trans type=\"CUT\" preFNum=\""<<cut<<"\" postFNum=\""<<cut+1<<"\"/>\n";
00370                     Output->Puts(oss.str());
00371                 }
00372             }
00373             Output->Puts(" </seg>\n");
00374             delete Output;
00375 
00376         }
00377 #endif // REPOSITORY_USED
00378     }
00379 
00380     void
00381     WriteMp7ShotSeg(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00382     {
00383         //IMPALA Segmentation and keyframes///////////////////////
00384         String fileName = vs->GetFile(fileId);
00385         String id = FileNameBase(fileName);
00386         int lastFrame = src->LastFrame();
00387         // todo: get fractions from RgbDataSrc
00388         //int fractions = 30000;
00389         int fractions = 25;
00390         Mpeg7Doc mp7(id, fileName, lastFrame + 1, fractions, true, "", "");
00391         int firstFrameInShot=0;
00392         int frameAtSemiCut = -1;
00393         //for(int i=0;i<mPredictions->CW();i++)
00394         for (int i=0 ; i<=lastFrame ; i++)
00395         {
00396             //If the probability is >mProbThresh then there was a cut 
00397             //between previous and current frame
00398             if ((mPredictions->Value(i,0) > mProbThresh) ||
00399                 (i == lastFrame))
00400             {
00401                 int realId = vs->GetFileId(fileId);
00402                 //String shotName = "shot" + MakeString(fileId+1) +
00403                 String shotName = "shot" + MakeString(realId+1) +
00404                     "_" + MakeString(mShotNr+1);
00405                 std::vector<String> keyNames;
00406                 keyNames.push_back(shotName + "_RKF");
00407                 if (frameAtSemiCut != -1)
00408                     keyNames.push_back(shotName + "_NRKF");
00409                 std::vector<int> keyFrames;
00410                 if (frameAtSemiCut == -1)
00411                 {
00412                     keyFrames.push_back((firstFrameInShot+i) / 2);
00413                 }
00414                 else
00415                 {
00416                     keyFrames.push_back((firstFrameInShot+frameAtSemiCut) / 2);
00417                     keyFrames.push_back((frameAtSemiCut+i) / 2);
00418                 }
00419                 mp7.AddShot(shotName, firstFrameInShot, i, keyNames,
00420                             keyFrames);
00421                 firstFrameInShot=i+1;
00422                 frameAtSemiCut = -1;
00423                 mShotNr++;
00424             }
00425             else if ((mPredictions->Value(i,0) > 0.8 * mProbThresh) &&
00426                      (i - firstFrameInShot > 25))
00427             {
00428                 frameAtSemiCut = i;
00429             }
00430         }
00431         Mpeg7DocWrite(&mp7, vs, fileId);
00432     }
00433 
00434     void
00435     WriteShotSimilarity(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00436     {
00437         int lastFrame = src->LastFrame();
00438         std::vector<String> names;
00439         names.push_back("ShotBoundary");
00440         Table::SimilarityTableSet simSet(names, lastFrame+1);
00441         Table::QuidTable* qTable = simSet.GetQuidTable();
00442         int idx = 0;
00443         Table::SimilarityTableSet::SimTableType* sTable = simSet.GetSimTable(idx);
00444         for (int i=0 ; i<=lastFrame ; i++)
00445         {
00446             Quid q = vs->GetQuidFrame(fileId, i);
00447             qTable->Add(q);
00448             Real64 v = mPredictions->Value(i,0) / 2; // to get between 0 and 1
00449             sTable->Add(v);
00450         }
00451         simSet.ComputeRanks(true);
00452 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00453         simSet.Save(vs, "Frames", "streamConcepts.txt", "no_model", "direct",
00454                     fileId, true);
00455 #else // REPOSITORY_USED
00456         Persistency::SimilarityTableSetLocator loc
00457             (vs->GetLocator(), false, "Frames", "streamConcepts.txt", "no_model",
00458              "direct", vs->GetAsPath(fileId));
00459         Persistency::SimilarityTableSetRepository().Add(loc, &simSet);
00460 #endif // REPOSITORY_USED
00461     }
00462 
00463     void
00464     WriteScores(String SrcName)
00465     {
00466     
00467 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00468         std::ostringstream oss;
00469 
00470         //Scores File
00471         char OutFileName[300];
00472         sprintf(OutFileName,"%s_%d-%g-%d.txt",SrcName.c_str(),
00473                                     mRadius,mSigma,mBinCount);
00474         Util::Database& Db = Util::Database::GetInstance();
00475         Db.MakeDir("ShotSegmentation","Scores",mMode,mRunName);
00476         String FileName=Db.GetFilePath("ShotSegmentation","Scores",mMode,mRunName,OutFileName,true,false);
00477         Util::IOBuffer* Output=Db.GetIOBuffer(FileName,false,false,"tmp");
00478         if(Output && Output->Valid())
00479         {
00480             ILOG_INFO("Writing Scores to "<<FileName);
00481             for (int i=0;i<mScores->CW();i++)
00482             {
00483                 oss<<i<<" "<<mScores->Value(i,0);
00484                 Output->Puts(oss.str());
00485                 oss.str( "" );
00486             }
00487             delete Output;
00488         }
00489 #endif // REPOSITORY_USED
00490 
00491     }
00492 
00493     void
00494     WriteLfvAndSvm(String SrcName, int fileId)
00495     {
00496 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00497         //First find all values below our treshold:
00498         //mScores<mTreshold
00499         Array::Array2dScalarInt32* TrainSet = 0;
00500         LessThanVal(TrainSet,mScores,mThreshold);
00501         
00502         std::ostringstream osssvm;
00503         std::ostringstream osslfv;
00504         
00505         //LFV File
00506         char OutFileName[300];
00507         sprintf(OutFileName,"%s_%s_%g_%d-%g-%d.lfv", SrcName.c_str(),
00508             mRunName.c_str(),mThreshold,mRadius,mSigma,mBinCount);
00509         Util::Database& Db = Util::Database::GetInstance();
00510         Db.MakeDir("ShotSegmentation","Lfv",mMode,mRunName);
00511         String FileName=Db.GetFilePath("ShotSegmentation","Lfv",mMode,mRunName,OutFileName,true,false);
00512         Util::IOBuffer* LfvOutput=Db.GetIOBuffer(FileName,false,false,"tmp");
00513         ILOG_INFO("Writing LFV to "<<FileName);
00514         //SVM File
00515         sprintf(OutFileName,"%s_%s_%g_%d-%g-%d.svm",SrcName.c_str(),
00516             mRunName.c_str(),mThreshold,mRadius,mSigma,mBinCount);
00517         Db.MakeDir("ShotSegmentation","Svm",mMode,mRunName);
00518         FileName=Db.GetFilePath("ShotSegmentation","Svm",mMode,mRunName,OutFileName,true,false);
00519         ILOG_INFO("Writing SVM to "<<FileName);
00520         Util::IOBuffer* SvmOutput=Db.GetIOBuffer(FileName,false,false,"tmp");
00521         if(LfvOutput && SvmOutput && LfvOutput->Valid() && SvmOutput->Valid())
00522         {
00523             ILOG_INFO("Writing Training Files!");
00524 
00525             //Find the local minimums, discard non-minimums
00526             //Make ROI to be i-R:i+R =>>TODO: Check Validity of borders
00527             for(int i = mCentered ? mRadius : mRadius - 1 ;
00528                     i < ( mCentered ? mScores->CW() - mRadius - 1
00529                                     :mScores->CW() - mRadius) ; i++)
00530             {
00531                 ILOG_INFO("Checking if LocalMin");
00532 
00533                 if ((TrainSet->Value(i,0) == 1)  ||  (((mMode=="Test")||(mMode=="EvalTest"))&&
00534                                                      (mCUTs->Value(i,0)==1)&&
00535                                                      (mCUTs->Value(i-1,0)==1)))
00536                 {
00537                     ILOG_INFO("Either LocalMin, or Creating Test set");
00538                     //Centered has 3 more features
00539                     int left  = mCentered ? i - mRadius : i - mRadius + 1;
00540                     int right = mCentered ? i + mRadius + 1 : i + mRadius ; 
00541                     int center = mCentered ? mRadius : mRadius-1;
00542                     Array2dScalarReal64* roi =
00543                       MakeRoi(mScores,Geometry::Rectangle(left,0,right,0));
00544                     //if it's a local min, or a CUT in test run
00545                     if((roi->Value(center,0)==PixMin(roi)) 
00546                                             ||(    ((mMode=="Test")||(mMode=="EvalTest"))
00547                                                 && (mCUTs->Value(i,0)   ==1)
00548                                                 && (mCUTs->Value(i-1,0) ==1)) )
00549 
00550                     {
00551                         bool isCut = ((mCUTs->Value(i-1,0) == 1) |
00552                                       (mCUTs->Value(i,0)   == 1) |
00553                                       (mCUTs->Value(i+1,0) == 1) );
00554 
00555                         ILOG_INFO("LocalMin is "<<(isCut?"a cut":"not a cut"));
00556 
00557                         if(mSymmetry!="Inv")
00558                         {
00559                             osssvm<<(isCut?1:-1);
00560                             osslfv<<fileId<<"_"<<i<<" "<<(isCut?1:-1);
00561                             
00562                             for(int j=0;j<roi->CW();j++)
00563                             {
00564                                 //if we are not going to use symmetry
00565                                 osslfv<<" "<<j+1<<":"<<roi->Value(j,0);
00566                                 osssvm<<" "<<j+1<<":"<<roi->Value(j,0);
00567                             }
00568                             SvmOutput->Puts(osssvm.str());
00569                             LfvOutput->Puts(osslfv.str());
00570                             osssvm.str("");
00571                             osslfv.str("");
00572                         }
00573                         if(mSymmetry!="None")
00574                         {
00575                             osssvm<<(isCut?1:-1);
00576                             osslfv<<fileId<<"_"<<i<<"_sym "<<(isCut?1:-1);
00577                             for(int j=0;j<roi->CW();j++)
00578                             {
00579                                 //if we are going to use symmetry,output reverse also
00580                                 osslfv<<" "<<j+1<<":"<<roi->Value(roi->CW()-j-1,0);
00581                                 osssvm<<" "<<j+1<<":"<<roi->Value(roi->CW()-j-1,0);
00582                             }
00583                             SvmOutput->Puts(osssvm.str());
00584                             LfvOutput->Puts(osslfv.str());
00585                             osssvm.str("");
00586                             osslfv.str("");
00587                         }
00588                     }
00589                 }
00590             }
00591             delete SvmOutput;
00592             delete LfvOutput;
00593         }
00594 #endif // REPOSITORY_USED
00595     }
00596 
00597     void
00598     HandleDoneFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00599     {
00600         if (mPredictOnly)
00601         {
00602             for (int i=0; i < mScores->CW() - mRadius - 1 ; i++)
00603                 Predict(i);
00604         }
00605         
00606         if (((mMode=="Run") || (mPredictOnly)) && mPredictOutput)
00607         { 
00608             WritePredictions();
00609         }
00610 
00612         //Storing Keyframes and Segmentation is handled in this function
00613 
00614         if (mMode=="Run")
00615         {
00616             if (!mGUI)   // If we're not in the walker mode, we do not output
00617             {            // impala shot data
00618                 WriteMp7ShotSeg(vs, fileId, src);
00619                 WriteShotSimilarity(vs, fileId, src);
00620             }
00621         }
00622 
00623         if ((mMode=="Train") || (mMode=="Test") ||
00624             (mMode=="EvalTrain") || (mMode=="EvalTest"))
00625         {
00626             String SrcName = mSrc->GetName();
00627             SrcName=Impala::FileNameBase(SrcName);
00628             //Write the scores data 
00629             WriteScores(SrcName);
00630             //We should also output the tresholded local minimum values
00631             WriteLfvAndSvm(SrcName, fileId);
00632         }
00633 
00635         //Clear the variables for the next file
00636         if (mScores != 0)
00637         {
00638             delete mScores;
00639             mScores = 0;
00640         }
00641         if (mPredictions != 0)
00642         {
00643             delete mPredictions;
00644             mPredictions=0;
00645         }
00646         if (mHistograms!=0)
00647         {
00648             for (int i=0 ; i<mWindowSize*mHistPerFrame ; i++)
00649             {   
00650                delete mHistograms[i];
00651             }
00652             delete[] mHistograms;
00653             mHistograms = 0;
00654         }
00655         if (mFeatures != 0)
00656         {
00657             delete mFeatures;
00658             mFeatures = 0;
00659         }
00660         if (mFeaturesReversed != 0)
00661         {
00662             delete mFeaturesReversed;
00663             mFeaturesReversed = 0;
00664         }
00665         if (mCUTs)
00666         {
00667             delete mCUTs;
00668             delete mFOIs;
00669             delete mDISs;
00670             delete mOTHs;
00671             delete mGroundTruth;
00672         }
00673     }
00674 
00675     //Accessors 
00676 
00677     int
00678     GetPredictionFrame()
00679     {
00680         //Return the earliest possible frame we can predict
00681         int DecisionFrame = mSrc->FrameNr()-mWindowSize;
00682         return (DecisionFrame>0) ? DecisionFrame : 0;
00683     }
00684     
00685     bool
00686     Blur()
00687     {
00688         return  mBlur;
00689     }
00690 
00691     Array2dScalarReal64* 
00692     GetCUTs()
00693     {
00694         return mCUTs;
00695     }
00696 
00697     Array2dScalarReal64* 
00698     GetFOIs()
00699     {
00700         return mFOIs;
00701     }
00702 
00703     Array2dScalarReal64* 
00704     GetDISs()
00705     {
00706         return mDISs;
00707     }
00708 
00709     Array2dScalarReal64* 
00710     GetOTHs()
00711     {
00712         return mOTHs;
00713     }
00714 
00715     Array2dScalarReal64* 
00716     GetScores()
00717     {
00718         return mScores;
00719     }
00720     
00721     Array2dScalarReal64* 
00722     GetPredictions()
00723     {
00724         return mPredictions;
00725     }
00726     
00727     Array2dScalarReal64* 
00728     GetWeights()
00729     {
00730         return mWeights;
00731     }
00732 
00733     double
00734     GetProbThresh()
00735     {
00736         return mProbThresh;
00737     }
00738  
00739     double
00740     GetScore(int i)
00741     {
00742         if(i<0)
00743             i=0;
00744         return mScores->Value(i,0);
00745     }
00746     
00747     int
00748     GetWindowSize()
00749     {
00750         return mWindowSize;
00751     }
00752 
00753     Vector::VectorTem<Real64>*
00754     GetFeatures()
00755     {
00756         return mFeatures;
00757     } 
00758     
00759     void
00760     Predict(int PredictFrame)
00761     {
00762         int PredictBase = mCentered? PredictFrame-mRadius : PredictFrame-mRadius+1; 
00763         int size = mCentered ? mWindowSize + 1 : mWindowSize;
00764         if (PredictBase<0)
00765         {
00766             mPredictions->SetValue(0.0, PredictFrame, 0);
00767             return;
00768         }
00769         
00770         //Update the feature vector
00771         for(int i=0;i<size;i++)
00772         {
00773             (*mFeatures)[i]=mScores->Value(PredictBase+i,0);
00774             (*mFeaturesReversed)[size-i-1]=mScores->Value(PredictBase+i,0);
00775             
00776         }
00777 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00778         if (mSvm)
00779         {
00780             double pf = mSvm->Predict(mFeatures);
00781             double pr = mSvm->Predict(mFeaturesReversed);
00782             double p = 0;
00783 
00784             if(mSymmetry=="None")
00785                 p=pf;
00786             else if(mSymmetry=="Avg")
00787                 p=(pr+pf)/2;
00788             else if(mSymmetry=="Or")
00789                 p= (pf > pr) ? pf : pr;
00790             else if(mSymmetry=="And")
00791                 p= (pf < pr) ? pf : pr;
00792 
00793             
00794             mPredictions->SetValue(1-p,PredictFrame,0);
00795         }
00796         else
00797         {
00798  #endif // REPOSITORY_USED
00799            Real64 minScore = Vector::ElemMin(*mFeatures);
00800             if (mFeatures->Elem(mCentered ? mRadius : mRadius-1) == minScore)
00801             {
00802                 mPredictions->SetValue((4.0-minScore) / 2.0, PredictFrame, 0);
00803             }
00804             else
00805             {
00806                 mPredictions->SetValue(0.0, PredictFrame, 0);
00807             }
00808 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00809         }
00810 #endif // REPOSITORY_USED
00811     }
00812 
00813 private:
00814 
00815     void
00816     BlurImage(Array2dScalarReal64*& channel,double sigma)
00817     {
00818 
00819         Array2dScalarReal64* blurred=0;
00820         RecGauss(blurred,channel,sigma,sigma,mBlurDer,mBlurDer,1);
00821         if(mBlurDer>0){
00822             Mul(channel,channel,blurred);
00823             DivVal(channel,channel,PixMax(blurred));
00824             RecGauss(blurred,channel,sigma,sigma,0,0,1);
00825         }
00826 
00827         delete channel;
00828         channel=blurred;
00829     }
00830 
00831     void
00832     UpdateHistograms(unsigned char* data)
00833     {
00834         HistType** tmpHist;
00835         tmpHist = new HistType*[mHistPerFrame];
00836         //Back up the first frame's histogram pointers
00837         for(int i=0; i<mHistPerFrame ;i++)
00838             tmpHist[i] = mHistograms[i];
00839         //Shift the rest of the histograms
00840         for(int i=0 ; i<(mWindowSize-1)*mHistPerFrame ; i++)
00841             mHistograms[i] = mHistograms[i+mHistPerFrame];
00842 
00843         for(int i=(mWindowSize-1)*mHistPerFrame; i<mWindowSize*mHistPerFrame ;i++)
00844             mHistograms[i]=tmpHist[i-(mWindowSize-1)*mHistPerFrame];
00845         delete [] tmpHist;
00846 
00847         Array::Array2dVec3Real64* srcWrap =
00848             Array::ArrayCreate<Array::Array2dVec3Real64>(mSrc->FrameWidth(),
00849                                                          mSrc->FrameHeight(),
00850                                                          0, 0);
00851 
00852         Array::MakeFromData2<Array::Array2dVec3Real64,Array::Array2dVec3UInt8>(srcWrap,data);
00853         
00855         //OOO
00856         //Array2dVec3Real64* srcOOO=0;
00857         //ColorSpace(srcOOO,srcWrap,Element::RGB,Element::OOO);
00858 
00859         Array::Array2dScalarReal64* srcO1 = 0;
00860         Array::Array2dScalarReal64* srcO2 = 0;
00861         Array::Array2dScalarReal64* srcO3 = 0;
00862 
00863         Array::ProjectRange(srcO1,srcWrap,1);
00864         Array::ProjectRange(srcO2,srcWrap,2);
00865         Array::ProjectRange(srcO3,srcWrap,3);
00866     
00867         if (mBlur)
00868         {
00869             BlurImage(srcO1,mBlurSigma);
00870             BlurImage(srcO2,mBlurSigma);
00871             BlurImage(srcO3,mBlurSigma);
00872         }
00873 
00874         int k = (mWindowSize-1)*mHistPerFrame-1;
00875 
00876         for(int i=0;i<mPyramid.NrLevels();i++){
00877             for (int j=0;j<mPyramid.NrRects(i);j++){
00878 
00879                 MakeHistogram1d(mHistograms[++k],srcO1,mPyramid.Rect(i,j));
00880                 if(mHistEq)
00881                     EqualizeHist(mHistograms[k]);
00882                 if(mHistNorm)
00883                     mHistograms[k]->Normalize();
00884                 
00885                 MakeHistogram1d(mHistograms[++k],srcO2,mPyramid.Rect(i,j));
00886                 if(mHistEq)
00887                     EqualizeHist(mHistograms[k]);
00888                 if(mHistNorm)
00889                     mHistograms[k]->Normalize();
00890 
00891                 MakeHistogram1d(mHistograms[++k],srcO3,mPyramid.Rect(i,j));
00892                 if(mHistEq)
00893                     EqualizeHist(mHistograms[k]);
00894                 if(mHistNorm)
00895                     mHistograms[k]->Normalize();
00896             }
00897         }
00898 
00899         delete srcWrap;
00900         //delete srcOOO;
00901 
00902         delete srcO1;
00903         delete srcO2;
00904         delete srcO3;
00905     }
00906 
00907     void
00908     EqualizeHist(HistType* h)
00909     {
00910         for(int i=0;i<h->Size();i++){
00911             Real64 tot = h->TotalWeight();
00912             Real64 cum = 0;
00913             for(int i=0 ; i<h->Size() ; i++)
00914             {
00915                 cum += h->Elem(i);
00916                 h->Elem(i) = cum / tot;
00917             }
00918         }
00919     }
00920 
00921     void
00922     ComputeSSWeights()
00923     {   
00924     
00925         for (int i=0;i<mWindowSize;i++)
00926         {
00927             for (int j=0;j<mWindowSize;j++)
00928             {
00929                 //OOO
00930                 Real64 weight=0;
00931                 for(int k=0;k<mHistPerFrame;k++){
00932                     if(mHistSim == "Intersection")
00933                         weight += Core::Vector::HistogramIntersection
00934                                         (*mHistograms[i*mHistPerFrame+k],
00935                                          *mHistograms[j*mHistPerFrame+k]);
00936                     else if(mHistSim == "Kullback")
00937                         weight += Core::Vector::KullbackDivergence
00938                                         (*mHistograms[i*mHistPerFrame+k],
00939                                          *mHistograms[j*mHistPerFrame+k]);
00940                 }
00941                 
00942                 if(mHistSim != "Kullback")
00943                     mWeights->SetValue(weight*mGauss->Value(mWindowSize+i-j,0),i,j);
00944                 else
00945                     mWeights->SetValue(pow(2.0,-weight)*mGauss->Value(mWindowSize+i-j,0),i,j);
00946             }
00947         }
00948 
00949     }
00950 
00951     Real64
00952     CalculateScores()
00953     {
00954         if(mNormW)
00955         {
00956             //Scale the weights for visualization
00957             MulVal(mWeights,mWeights,1/PixMax(mWeights));
00958         }
00959         int center = mCentered ? mRadius +1 : mRadius;
00960 
00961         Real64 DisSimA=0;
00962         Real64 DisSimB=0;
00963         Real64 SimA=0;
00964         Real64 SimB=0;
00965         //include ==mRadius also
00966         for(int i=0;i<mRadius;i++)
00967         {
00968             for(int j=0;j<mRadius;j++)
00969             {
00970                 SimA+=mWeights->Value(i,j);
00971                 DisSimA+=mWeights->Value(i,j+center);
00972             }
00973         }
00974 
00975         for(int i=center;i<mWindowSize;i++)
00976         {
00977             for(int j=0;j<mRadius;j++)
00978             {
00979                 SimB+=mWeights->Value(i,j+center);
00980                 DisSimB+=mWeights->Value(i,j);
00981             }
00982             
00983         }
00984         Real64 CutAB=DisSimA+DisSimB;
00985         Real64 NCutAB=SimA+SimB;
00986 
00987         Real64 s = CutAB/SimA+CutAB/SimB;
00988         Real64 Ns=NCutAB/DisSimA+NCutAB/DisSimB;
00989 
00990         if((SimA*SimB==0)||(DisSimA*DisSimB==0))
00991         {
00992             return 4;
00993         }
00994 
00995         if(mSim=="+")
00996             return s;
00997         else if(mSim=="-")
00998             return Ns;
00999         else if(mSim=="log+")
01000             return log(s);
01001         else if(mSim=="log-")
01002             return log(Ns);
01003         return 0;
01004     }
01005     
01006     void 
01007     ReadGroundTruth()
01008     {
01009 
01010         String XMLName=Impala::FileNameBase(mSrc->GetName());
01011         XMLName= mRefDir + mRefPrefix + XMLName + String(".xml");
01012 
01013         //Create a new xml reader
01014         Persistency::XmlFileReader* xfr = new Persistency::XmlFileReader;
01015         //If the file exists or not
01016         if(!FileExists(XMLName))
01017         {
01018             //there is no groundtruth data, so that means it is 
01019             //not one of the training videos.
01020             ILOG_INFO("File Does not exist "<<XMLName);
01021             return;
01022         }
01023         if(mVerbose>1)
01024             ILOG_INFO("Reading Ground truth from "<<XMLName);
01025 
01026         XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc=
01027         xfr->Read(XMLName);
01028 
01029         //Find all nodes named trans
01030         XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* elems=
01031         xfr->FindElementsByName(doc,"trans");
01032 
01033         for (XMLSize_t i = 0; i< elems->getLength(); i++)
01034         {
01035             String type=xfr->GetAttributeValue(elems->item(i)->getAttributes(),"type");
01036             int col=0;
01037             if(type=="CUT")
01038                 col=0;
01039             if(type=="DIS")
01040                 col=1;
01041             if(type=="OTH")
01042                 col=2;
01043             if(type=="FOI")
01044                 col=3;
01045             int start=atoi(xfr->GetAttributeValue(elems->item(i)->getAttributes(),"preFNum").c_str());
01046             int end=atoi(xfr->GetAttributeValue(elems->item(i)->getAttributes(),"postFNum").c_str());
01047             //If the gradual transition is less than mShortGrad, add it as a CUT
01048             if(start-end<mShortGrad){
01049                 mGroundTruth->SetValue(1,(start+end)/2-1,0);
01050                 mGroundTruth->SetValue(1,(start+end)/2,0);
01051             }
01052             for(int i=start;i<=end;i++)
01053             {
01054                 mGroundTruth->SetValue(1,i,col);
01055             }
01056         }
01057         delete xfr;
01058 
01059         SetPart(mCUTs, mGroundTruth, 0,0, mGroundTruth->CW(), 1, 0, 0);
01060         SetPart(mDISs, mGroundTruth, 0,1, mGroundTruth->CW(), 1, 0, 0);
01061         SetPart(mOTHs, mGroundTruth, 0,2, mGroundTruth->CW(), 1, 0, 0);
01062         SetPart(mFOIs, mGroundTruth, 0,3, mGroundTruth->CW(), 1, 0, 0);
01063 
01064     } 
01065 
01066     int mVerbose;
01067     double mThreshold;
01068     double mProbThresh;
01069     int mRadius;
01070     double mSigma;
01071     double mBlurSigma;
01072     int mBinCount;
01073     bool mHistEq;
01074     bool mHistNorm;
01075     bool mNormW;
01076     bool mBlur;
01077     bool mCentered;
01078     int  mBlurDer;
01079     String mHistSim;
01080     String mSymmetry;
01081     int mWindowSize;
01082     int mShortGrad;
01083     
01084     String mSvmModelFile;
01085     String mDataDir;
01086     String mRefDir;
01087     String mRefPrefix;
01088     String mMode;
01089     String mRunName;
01090     bool   mGUI;
01091     bool   mThresholdOnly;
01092     bool   mPredictOnly;
01093     bool   mPredictOutput;
01094     bool   mDoProcessing;
01095 
01096 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
01097     Core::Training::Svm* mSvm;
01098 #endif // REPOSITORY_USED
01099     
01100     Stream::RgbDataSrc* mSrc;
01101     
01102     Array2dScalarReal64* mGauss;
01103     Array2dScalarReal64* mWeights;
01104     Array2dScalarReal64* mScores;
01105     Array2dScalarReal64* mPredictions;
01106     
01107     Array2dScalarReal64* mGroundTruth;
01108     Array2dScalarReal64* mCUTs;
01109     Array2dScalarReal64* mDISs;
01110     Array2dScalarReal64* mOTHs;
01111     Array2dScalarReal64* mFOIs;
01112     
01113     Vector::VectorTem<Real64>* mFeatures;
01114     Vector::VectorTem<Real64>* mFeaturesReversed;
01115     
01116     String     mSim;
01117     HistType** mHistograms;
01118 
01119     Reporter*     mReporter;
01120     int           mShotNr;
01121 
01122     Geometry::RectanglePyramid mPyramid;
01123     int mHistPerFrame;
01124     int mPyrL,mPyrU;
01125 
01126     ILOG_VAR_DEC;
01127 };
01128 
01129 ILOG_VAR_INIT(ShotSegmenter, Impala.Core.VideoSet);
01130 
01131 } // namespace VideoSet
01132 } // namespace Core
01133 } // namespace Impala
01134 
01135 #endif

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