00001 #ifndef Impala_Visualization_RotorBrowser_RotorBrowserGui_h
00002 #define Impala_Visualization_RotorBrowser_RotorBrowserGui_h
00003
00004 #include "RotorBrowser.h"
00005
00006
00007 #include "OglGui/TextArea.h"
00008 #include "OglGui/Window.h"
00009
00010 #include "Visualization/ImageSet.h"
00011 #include "Visualization/Window.h"
00012 #include "Visualization/VideoMinimap.h"
00013
00014 #include "Core/Trec/VisualQueryEngine.h"
00015 #include "Sandbox/ork/ProgramNameReader.h"
00016
00017 namespace Impala {
00018 namespace Visualization {
00019 namespace RotorBrowser {
00020
00021 class RotorBrowserGUI: public Visualization::Window,
00022 public RotorBrowserListener,
00023 public Visualization::ImagesListener
00024 {
00025 public:
00026 typedef Core::Trec::KeyframeResult KeyframeResult;
00027 typedef Core::Trec::ShotResult ShotResult;
00028 typedef Core::Trec::VisualQueryEngine VisualQueryEngine;
00029 typedef Core::Trec::ThreadSet ThreadSet;
00030 typedef Core::VideoSet::Segmentation Segmentation;
00031 typedef Core::VideoSet::SegmentationDocument SegmentationDocument;
00032 typedef std::list<RotorBrowserContext*> RotorBrowserContextList;
00033 typedef std::list<KeyframeResult> KeyframeResultList;
00034
00035 RotorBrowserGUI(OglGui::Window *parent, int w, int h,ThreadSet *threadset,
00036 SegmentationDocument *segdoc, int imW, int imH,
00037 double imScale, int controlId, bool showLatestBookmarks,
00038 bool enableMinimap = true) :
00039 Visualization::Window(parent, w, h, true)
00040 {
00041 mThreadSet = threadset;
00042 mSegDoc = segdoc;
00043 mRotorBrowser = NULL;
00044 mRotorBrowserInfo = NULL;
00045 mLastVisualKeyframe = -1;
00046 mLastVisualMode = -1;
00047 mMinimapEnabled = enableMinimap;
00048
00049 SetControlId(controlId);
00050
00051 BuildGui(imW, imH, imScale, showLatestBookmarks);
00052
00053
00054
00055 }
00056
00057 RotorBrowser* Browser()
00058 {
00059 return mRotorBrowser;
00060 }
00061
00062 void SetBrowseMode(int mode)
00063 {
00064 mRotorBrowser->SetBrowseMode(mode);
00065 }
00066
00067 void SetInitialQueryToMovies()
00068 {
00069 ILOG_DEBUG("setting shots_initialquery to first shot in each movie");
00070
00071
00072
00073 int nrVideos = mThreadSet->GetKeyframes()->GetNrVideos();
00074 std::list<ShotResult> shots;
00075 for (int i=0; i < nrVideos; i++)
00076 {
00077 int frame = mThreadSet->GetKeyframes()->GetFirstKeyframeVideo(i);
00078 int shot = mThreadSet->GetKeyframes()->GetShotId(frame);
00079 ShotResult r;
00080 r.shotid = shot;
00081 r.score = 1.0;
00082 r.rank = i + 1;
00083 shots.push_back(r);
00084 }
00085 mThreadSet->RemoveThread("shots_initialquery");
00086 mThreadSet->AddThreadShots("initialquery", shots);
00087 mRotorBrowser->ValidateContext("shots_initialquery");
00088 mRotorBrowser->UpdateViewsToContext();
00089 int mode = mRotorBrowser->GetBrowseMode();
00090 if (mode == RotorBrowser::MODE_CROSSBROWSER)
00091 mRotorBrowser->ReloadCrossBrowser();
00092 else if(mode == RotorBrowser::MODE_FORKBROWSER)
00093 mRotorBrowser->ReloadForkBrowser();
00094 else
00095 mRotorBrowser->ReloadInitial();
00096 }
00097
00098 void DoQueryByRegion(int keyframe, float x, float y, float w, float h)
00099 {
00100 ILOG_DEBUG("external DoQueryByRegion for " << keyframe);
00101 mRotorBrowser->OnRectangleSelectByKeyframe(keyframe, x, y, w, h);
00102 }
00103
00104 void ResetCrossBrowser()
00105 {
00106 mRotorBrowser->UpdateViewsToContext();
00107 mRotorBrowser->ReloadCrossBrowser();
00108 }
00109
00110 void AddRotorBrowserListener(RotorBrowserListener *target)
00111 {
00112 mListeners.push_back(target);
00113 }
00114
00115 void ResetRanking()
00116 {
00117 ILOG_DEBUG("ResetRanking()");
00118 mRotorBrowser->ResetRanking();
00119 }
00120
00121 void FocusToBrowser()
00122 {
00123 mRotorBrowser->TakeFocus();
00124 }
00125
00126
00127 void PressKey(int c, int state = 0)
00128 {
00129 mRotorBrowser->TakeFocus();
00130 mRotorBrowser->KeyboardFunc(c, state);
00131 }
00132
00133 void SetProgramNames(Samples::ProgramNameReader *programs)
00134 {
00135 mRotorBrowser->SetProgramNames(programs);
00136 }
00137
00138
00139 int GetCenterShot()
00140 {
00141 if (mRotorBrowser != 0 && mRotorBrowser->GetActiveContext() != 0)
00142 return mRotorBrowser->GetActiveContext()->GetCenter();
00143 return -1;
00144 }
00145
00146 bool GetShowMinimap()
00147 {
00148 return mMinimapVisible;
00149 }
00150
00151 void SetShowMinimap(bool doShow)
00152 {
00153 if (mMinimapEnabled)
00154 {
00155 mMinimapVisible = doShow;
00156 mMinimap->SetVisible(doShow);
00157 if (mRotorBrowser != 0)
00158 mRotorBrowser->SetMinimapEnabled(doShow);
00159 }
00160 }
00161
00162 virtual void HandleActivate()
00163 {
00164 ILOG_DEBUG( "HandleActivate()" );
00165 mRotorBrowser->ReloadInitial();
00166 }
00167
00168
00169 private:
00170
00171
00172
00173
00174
00175
00176
00177 void
00178 BuildGui(int imW, int imH, double viewScale, bool showLatestBookmarks)
00179 {
00180 int yOff = showLatestBookmarks ? 80 : 0;
00181 mRotorBrowser =
00182 new RotorBrowser(this, 0, yOff, W(), H()-yOff, mThreadSet, mSegDoc);
00183 mRotorBrowser->SetBorderFillShaded(1);
00184 mRotorBrowser->SetBorderType(5);
00185 mRotorBrowser->SetRoundness(10,10,10,10);
00186 mRotorBrowser->ConnectTo(this, ALLSIDES );
00187 mRotorBrowser->SetRotorBrowserListener(this);
00188
00189 viewScale = viewScale / 2;
00190
00191
00192 mLatestBookmarks = 0;
00193 if (showLatestBookmarks)
00194 {
00195
00196 OglGui::Window *bookmarkW =
00197 new OglGui::Window(this, 4, 28, W()-8, imH*viewScale+8);
00198 int nrImOnRow = bookmarkW->W() / (imW * viewScale);
00199 mLatestBookmarks = new ImageSet(bookmarkW, imW, imH, viewScale,
00200 nrImOnRow, 1);
00201 mLatestBookmarks->SetImagesListener(this, IM_BOOKMARKS);
00202 mLatestBookmarks->ActivateInfoBox(false);
00203 mLatestBookmarks->SetAllowDragging(false);
00204 mMaxBookmarkViews = nrImOnRow * 1;
00205 }
00206
00207
00208 mMinimap = 0;
00209 mMinimapVisible = false;
00210 if (mMinimapEnabled)
00211 {
00212 Segmentation* seg = mThreadSet->GetSegmentation();
00213 MapFunction *f = new VideoSquareMapFunction(seg,100,100);
00214 mMinimap = new VideoMinimap(f, this, W()-220, H()-220, 200, 200);
00215 mMinimap->SetRoundness(2,2,2,2);
00216 mMinimap->SetBorderType(4);
00217 mMinimap->SetBorderFillShaded(2);
00218 mMinimap->EnablePreviewWindow(mThreadSet);
00219 mRotorBrowser->RegisterShotTrails(mMinimap);
00220 mMinimapVisible = true;
00221 }
00222 }
00223
00224 private:
00225 virtual void KeyEvent(OglGui::Window *src, int c, int state)
00226 {
00227 ILOG_DEBUG( "KeyEvent(" << c << ", " << state << ")" );
00228 switch (c) {
00229 case 'm':
00230 ILOG_USER( "KB: set initialquery to movie start positions" );
00231 SetInitialQueryToMovies();
00232 break;
00233 }
00234 mRotorBrowser->TakeFocus();
00235 }
00236
00237 void Reset()
00238 {
00239 ILOG_DEBUG( "Reset()" );
00240 if (mLatestBookmarks)
00241 mLatestBookmarks->RemoveImages();
00242 mRotorBrowser->ClearViewedCache();
00243 }
00244
00245 virtual void ResetBrowserEvent()
00246 {
00247 Reset();
00248 }
00249
00250 virtual void
00251 ContextMoveEvent(OglGui::Window* src, int direction, int position)
00252 {
00253 ILOG_DEBUG( "MoveEvent: " << direction << " position = " << position );
00254 SetRotorText();
00255
00256 for (int i=0; i<mListeners.size();i++)
00257 mListeners[i]->ContextMoveEvent(src, direction, position);
00258
00259
00260
00261 }
00262
00263 virtual void
00264 ContextChangeEvent(OglGui::Window* src, RotorBrowserContext *newcontext)
00265 {
00266 SetRotorText();
00267 ILOG_DEBUG("ContextChangeEvent: new context = "<<newcontext->GetName());
00268 for (int i=0; i<mListeners.size();i++)
00269 mListeners[i]->ContextChangeEvent(src, newcontext);
00270
00271 }
00272
00273 virtual void
00274 BookmarkEvent(OglGui::Window* src, int shotid, bool isbookmarked)
00275 {
00276 ILOG_DEBUG( "BookmarkEvent: " << shotid << ": " << isbookmarked );
00277
00278 for (int i=0; i<mListeners.size();i++)
00279 mListeners[i]->BookmarkEvent(src, shotid, isbookmarked);
00280
00281 if (!mLatestBookmarks)
00282 return;
00283
00284 if (isbookmarked)
00285 {
00286 mLatestBookmarks->AddImage(mThreadSet->GetImageByShotID(shotid),
00287 "Direct",mThreadSet->GetShotName(shotid),
00288 true, false, shotid);
00289 int nrIm = mLatestBookmarks->GetNrImages();
00290 if (nrIm > 0)
00291 mLatestBookmarks->MoveImageTo(nrIm-1, 0);
00292 if (mLatestBookmarks->GetNrImages() > mMaxBookmarkViews)
00293 mLatestBookmarks->RemoveImageByIndex(nrIm-1);
00294 else
00295 mLatestBookmarks->Redraw();
00296 }
00297 else
00298 {
00299 mLatestBookmarks->RemoveImageById(shotid);
00300 mLatestBookmarks->Redraw();
00301 }
00302 }
00303
00304 void SetRotorText()
00305 {
00306 if (mRotorBrowserInfo == NULL)
00307 return;
00308 RotorBrowserContext* actContext = mRotorBrowser->GetActiveContext();
00309 std::ostringstream m;
00310 m << "Active context: " << actContext->GetNiceName() << std::endl;
00311 m << "Current position: " << actContext->GetCenter() << std::endl;
00312 m << "Other contexts (" << mRotorBrowser->GetNrActiveContexts()-1;
00313 m << "): " << std::endl;
00314
00315 RotorBrowserContextList contexts = mRotorBrowser->GetOtherContexts();
00316 RotorBrowserContextList::const_iterator context;
00317
00318 for (context = contexts.begin(); context != contexts.end(); context++)
00319 {
00320 m << " " << (*context)->GetNiceName() << " - " <<
00321 (*context)->GetThread()->GetShotPosition((*context)->GetCenter())
00322 << std::endl;
00323 }
00324 mRotorBrowserInfo->SetText(m.str());
00325 }
00326
00327
00328 virtual void ImageSelectionEvent(Visualization::ImagesWindow* src,
00329 int imIndex, void* listenerData)
00330 {
00331
00332 if (listenerData == (void*) IM_VISRESULTS && mLastVisualKeyframe >= 0)
00333 {
00334 int browseMode = mRotorBrowser->GetBrowseMode();
00335 if (browseMode == RotorBrowser::MODE_CROSSBROWSER)
00336 {
00337 ILOG_USER("set shots_initialquery to visual set from bottom " <<
00338 "view using keyframe " << mLastVisualKeyframe );
00339 SetInitialQueryToVisual();
00340 }
00341 else
00342 {
00343 ILOG_USER("adding results from bottom view to browser using " <<
00344 "keyframe " << mLastVisualKeyframe );
00345 AddVisualToBrowser();
00346 }
00347 }
00348
00349
00350 if (listenerData == (void*)IM_BOOKMARKS)
00351 {
00352 ILOG_USER( "unbookmark " << imIndex << " from bottom view" );
00353 int row = Core::Column::Find(mSegDoc->GetBookmarked()->GetColumn1(),
00354 imIndex, 0,
00355 mSegDoc->GetBookmarked()->Size());
00356 Core::Table::RemoveRow(mSegDoc->GetBookmarked(), row);
00357 mLatestBookmarks->RemoveImageById(imIndex);
00358 mLatestBookmarks->Redraw();
00359 mRotorBrowser->Redraw();
00360 }
00361
00362 mRotorBrowser->TakeFocus();
00363 }
00364
00365 void AddVisualToBrowser()
00366 {
00367 if (mLastVisualMode == 1)
00368 {
00369 ILOG_DEBUG( "adding last query by region result to browser" );
00370 std::list<ShotResult> shots;
00371 std::map<int,bool> seen;
00372 int lastshot = mThreadSet->GetKeyframes()
00373 ->GetShotId(mLastVisualKeyframe);
00374 for (KeyframeResultList::iterator i = mLastVisualKeyframes.begin();
00375 i != mLastVisualKeyframes.end(); i++)
00376 {
00377 ShotResult r;
00378 int frameID = i->keyframeid;
00379 if (frameID == -1)
00380 {
00381 ILOG_WARN("AddVisualToBrowser: " <<
00382 "WARNING: erroneous frame in set." );
00383 continue;
00384 }
00385 int shotID = mThreadSet->GetKeyframes()->GetShotId(frameID);
00386 if (seen.find(shotID) == seen.end())
00387 {
00388 r.shotid = shotID;
00389 r.score = i->score;
00390 r.rank = i->rank;
00391 shots.push_back(r);
00392 seen[shotID] = true;
00393 }
00394 }
00395 mThreadSet->AddThreadShots("visual " + MakeString(lastshot), shots);
00396 }
00397 else
00398 {
00399 ILOG_DEBUG( "adding last visually similar result to browser" );
00400 VisualQueryEngine *e = new VisualQueryEngine(mThreadSet, 200);
00401 int lastVis = mLastVisualKeyframe;
00402 KeyframeResultList shots = e->QueryVisual(lastVis,true);
00403 int lastshot = mThreadSet->GetKeyframes()->GetShotId(lastVis);
00404 mThreadSet->AddThreadShots("visual " + MakeString(lastVis), shots);
00405 }
00406 }
00407
00408
00409 void SetInitialQueryToVisual()
00410 {
00411 if (mLastVisualMode == 1)
00412 {
00413 ILOG_DEBUG("setting shots_initialquery to " <<
00414 "last query by region result");
00415 mThreadSet->RemoveThread("shots_initialquery");
00416 std::list<ShotResult> shots;
00417 std::map<int,bool> seen;
00418 for (KeyframeResultList::iterator i=mLastVisualKeyframes.begin();
00419 i !=mLastVisualKeyframes.end(); i++)
00420 {
00421 ShotResult r;
00422 int frameID = i->keyframeid;
00423 if (frameID == -1)
00424 {
00425 ILOG_WARN( "SetInitialQueryToVisual: " <<
00426 "WARNING: erroneous frame in set." );
00427 continue;
00428 }
00429 int shotID = mThreadSet->GetKeyframes()->GetShotId(frameID);
00430 if (seen.find(shotID) == seen.end())
00431 {
00432 r.shotid = shotID;
00433 r.score = i->score;
00434 r.rank = i->rank;
00435 shots.push_back(r);
00436 seen[shotID] = true;
00437 }
00438 }
00439 mThreadSet->AddThreadShots("initialquery", shots);
00440 mRotorBrowser->ReloadCrossBrowser();
00441 }
00442 else
00443 {
00444 ILOG_DEBUG("setting shots_initialquery to " <<
00445 "last visually similar result" );
00446 mThreadSet->RemoveThread("shots_initialquery");
00447 VisualQueryEngine *e = new VisualQueryEngine(mThreadSet, 200);
00448 KeyframeResultList shots = e->QueryVisual(mLastVisualKeyframe,true);
00449 mThreadSet->AddThreadShots("initialquery", shots);
00450 mRotorBrowser->ReloadCrossBrowser();
00451 }
00452 }
00453
00454 int mMaxBookmarkViews;
00455 int mNrVisualShown;
00456 int mLastVisualKeyframe;
00457 int mLastVisualMode;
00458
00459 bool mMinimapEnabled;
00460 bool mMinimapVisible;
00461
00462 ThreadSet* mThreadSet;
00463 SegmentationDocument* mSegDoc;
00464 RotorBrowser* mRotorBrowser;
00465 OglGui::TextArea* mRotorBrowserInfo;
00466 Visualization::ImageSet* mLatestBookmarks;
00467 Visualization::VideoMinimap* mMinimap;
00468 KeyframeResultList mLastVisualKeyframes;
00469
00470 std::vector<RotorBrowserListener*> mListeners;
00471
00472 static const int IM_BOOKMARKS = 1;
00473 static const int IM_VISRESULTS = 2;
00474
00475 ILOG_VAR_DEC;
00476
00477 };
00478
00479 ILOG_VAR_INIT(RotorBrowserGUI, Visualization.RotorBrowser);
00480
00481 }
00482 }
00483 }
00484 #endif
00485