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
00061 mReporter = reporter;
00062
00063 mScores=0;
00064 mPredictions=0;
00065 mFeatures=0;
00066 mFeaturesReversed=0;
00067 mHistograms=0;
00068
00069
00070 mSim = options.GetString ("SSSim","+");
00071 mHistSim = options.GetString ("SSHistSim","Intersection");
00072 mSymmetry = options.GetString ("SSSymmetry","None");
00073
00074
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
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);
00092
00093
00094 mMode = options.GetString ("SSMode","Run");
00095 mRunName = options.GetString ("SSRunName","NoRunName");
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
00104 mDataDir = options.GetString ("data");
00105 mRefDir = options.GetString ("SSRefDir");
00106 if(mRefDir==""){
00107 mRefDir=mDataDir+"/ShotSegmentation/ref";
00108 }
00109
00110
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
00182
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
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
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
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
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
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
00293
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
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
00367
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
00384 String fileName = vs->GetFile(fileId);
00385 String id = FileNameBase(fileName);
00386 int lastFrame = src->LastFrame();
00387
00388
00389 int fractions = 25;
00390 Mpeg7Doc mp7(id, fileName, lastFrame + 1, fractions, true, "", "");
00391 int firstFrameInShot=0;
00392 int frameAtSemiCut = -1;
00393
00394 for (int i=0 ; i<=lastFrame ; i++)
00395 {
00396
00397
00398 if ((mPredictions->Value(i,0) > mProbThresh) ||
00399 (i == lastFrame))
00400 {
00401 int realId = vs->GetFileId(fileId);
00402
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;
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
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
00498
00499 Array::Array2dScalarInt32* TrainSet = 0;
00500 LessThanVal(TrainSet,mScores,mThreshold);
00501
00502 std::ostringstream osssvm;
00503 std::ostringstream osslfv;
00504
00505
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
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
00526
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
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
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
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
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
00613
00614 if (mMode=="Run")
00615 {
00616 if (!mGUI)
00617 {
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
00629 WriteScores(SrcName);
00630
00631 WriteLfvAndSvm(SrcName, fileId);
00632 }
00633
00635
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
00676
00677 int
00678 GetPredictionFrame()
00679 {
00680
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
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
00837 for(int i=0; i<mHistPerFrame ;i++)
00838 tmpHist[i] = mHistograms[i];
00839
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
00856
00857
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
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
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
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
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
01014 Persistency::XmlFileReader* xfr = new Persistency::XmlFileReader;
01015
01016 if(!FileExists(XMLName))
01017 {
01018
01019
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
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
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 }
01132 }
01133 }
01134
01135 #endif