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

SimilarityTimeLine.h

Go to the documentation of this file.
00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00002 // Show impala concept similarities on a WindowTimeLine.
00003 //
00004 // NOTE: - Assumed that similarities are within range [0..1]
00005 //       - Based on fix 25 fps -> 1 frame 40 ms
00006 // NOTE: Only 13 colors properly chosen, and only 20 colors defined
00007 //       When using more than 20 concepts use AddSimColor
00008 // Author: Richard van Balen
00009 
00010 #ifndef Impala_Visualization_SimilarityTimeLine_h
00011 #define Impala_Visualization_SimilarityTimeLine_h
00012 
00013 #include "Visualization/TimeLineViewStrip.h"
00014 #include "Visualization/SimilarityTimeLineListener.h"
00015 #include "Core/Table/SimilarityTableSet.h"
00016 
00017 static char*
00018 sColorNamesSTL[] = {
00019     "red",
00020     "green",
00021     "blue",
00022     "magenta",
00023     "cyan",
00024     "yellow",
00025     "orange",
00026     "teal",
00027     "brown",
00028     "tomato",
00029     "DarkMagenta",
00030     "SoftBlue",
00031     "YellowGreen", // below this line colors not chosen optimally
00032     "PeachPuff", 
00033     "SaddleBrown",
00034     "SeaGreen",
00035     "SkyBlue",
00036     "Silver",
00037     "SlateBlue",
00038     "Violet",
00039     ""
00040 };
00041 
00042 
00043 namespace Impala {
00044 namespace Visualization {
00045 
00046 class  SimilarityTimeLine :  public TimeLineViewStrip
00047 {
00048 public:
00049     typedef Core::Table::SimilarityTableSet     SimilarityTableSet;
00050     typedef SimilarityTableSet::SimTableType    SimTableType;
00051     typedef std::vector<float>                  FloatVector;
00052     typedef std::vector<FloatVector*>           Averages;
00053 
00054 
00055     SimilarityTimeLine(int x, int y, int w, int h, int nViews) :
00056         TimeLineViewStrip(x,y,w,h,nViews)
00057     {
00058         Init(w,h);
00059     }
00060 
00061     SimilarityTimeLine(OglGui::Window* parent, int w, int h, int nViews) :
00062         TimeLineViewStrip(parent,w,h,nViews)
00063     {
00064         Init(w,h);
00065     }
00066 
00067     SimilarityTimeLine(OglGui::Window* parent, int x, int y, int w, int h,
00068                        int nViews) :
00069         TimeLineViewStrip(parent,x,y,w,h,nViews)
00070     {
00071         Init(w,h);
00072     }
00073 
00074     void
00075     SetListener(SimilarityTimeLineListener* listener, void* listenerData = 0)
00076     {
00077         mListener = listener;
00078         mListenerData = listenerData;
00079     }
00080 
00081     virtual void PublishCurrentChanged()
00082     {
00083         if (!mListener)
00084             return;
00085         mListener->CurrentChanged(this, mCurrent, mListenerData);
00086     }
00087 
00088     void SetSimilarityTableSet(SimilarityTableSet* simSet)
00089     {
00090         if (mSimSet)
00091             mVisibleConcepts.clear();
00092         if ((mSimSet = simSet) == 0)
00093             return;
00094         for (int i=0; i<mSimSet->NrTables(); i++)
00095             mVisibleConcepts.push_back(true);
00096     }
00097 
00098     void SetAverages(Averages* averages, FloatVector* maxima, FloatVector* means)
00099     {
00100         mAverages = averages;
00101         mMeans = means;
00102         mMaxima = maxima;
00103     }
00104 
00105     void AddSimColor(ULONG col)
00106     {
00107         mSimColors.push_back(col);
00108     }
00109 
00110     void SetSimColor(int id, ULONG col)
00111     {
00112         if (id > ((int)mSimColors.size())-1)
00113             return;
00114         mSimColors[id] = col;
00115     }
00116 
00117     ULONG GetSimColor(int id)
00118     {
00119         if (id > ((int)mSimColors.size())-1)
00120             return oglBLACK;
00121         return mSimColors[id];
00122     }
00123 
00124     int NrColors()
00125     {
00126         return mSimColors.size();
00127     }
00128 
00129     void SetShowSim(int id, bool show)
00130     {
00131         if (id<0 || id > ((int)mVisibleConcepts.size())-1)
00132             return;
00133         mVisibleConcepts[id] = show;
00134     }
00135 
00136     bool GetShowSim(int id)
00137     {
00138         if (id<0 || id > ((int)mVisibleConcepts.size())-1)
00139             return false;
00140         return mVisibleConcepts[id];
00141     }
00142 
00143     void NeedleOverConcepts()
00144     {
00145         OglGui::ZoomShiftRuler::DrawNeedle();
00146     }
00147 
00148     void PercMaxVal(float perc)       { mPercMax = perc; }
00149     void PercMaxMeanVal(float perc)   { mPercMaxMean = perc; }
00150     void ShowClassify(bool mode=true) { mShowClassify = mode; }
00151 
00152     bool PassTest(float sim, float maxim, float mean)
00153     {
00154         return (sim > mPercMax*maxim || (sim>mean+(maxim-mean)*mPercMaxMean));
00155     }
00156 
00157     void DrawHelpLines(int lineMax, int hRange)
00158     {
00159         OGC myOGC;
00160             OGCSave( &myOGC );
00161 
00162         ULONG col = oglGREY;
00163         SetSolidLineColor(col);
00164         SetStipple((short)oglDot);
00165         for (int i=0; i<4; i++)
00166         {
00167             int y = lineMax-i*hRange/4;
00168             DrawLine(24,y,W(),y);
00169             oglSys.PosColPrintf(mOglWnd,0,y-6,col,"%.2f",1.0f-i*0.25f);
00170         }
00171         SetStipple((short)oglSolid);
00172         if (mHelpLineActive)
00173         {
00174             if (mHelpLineY <= lineMax && mHelpLineY >= mAxisY)
00175             {
00176                 DrawLine(20,mHelpLineY,W()-20,mHelpLineY);
00177                 float val = (mHelpLineY-mAxisY)/(float)hRange;
00178                 int offY = (mHelpLineY - mAxisY > 16) ? -16 : 4;
00179                 oglSys.ShadowPrintf(mOglWnd,mHelpLineX+14,mHelpLineY+offY,
00180                                     oglDARKGREY,oglWHITE,"%0.2f",val);
00181             }
00182         }
00183         SetStipple((short)oglSolid);
00184     }
00185 
00186     void DrawAverages(int idx, int startFrame, int endFrame, int inc,
00187                       bool test, bool norm, int opaq, int hRange, int lineW)
00188     {
00189         if (!mAverages || (*mMaxima)[idx] < 0.20 || !mShowClassify)
00190             return;
00191 
00192         FloatVector*  avgVector = (*mAverages)[idx];
00193         float         maxim     = (*mMaxima)[idx];
00194         float         means     = (*mMeans)[idx];
00195         float         lineY     = H()-(idx+1)*5;
00196 
00197         if (startFrame > (*avgVector).size()-1)
00198             startFrame = (*avgVector).size()-1;
00199 
00200         if (endFrame > (*avgVector).size()-1)
00201             endFrame = (*avgVector).size()-1;
00202 
00203         int bInfo[3];
00204         oglSys.StartBlend(bInfo);
00205 
00206         ULONG col = mSimColors[idx%mSimColors.size()];
00207         UCHAR r,g,b;
00208         COLOR2RGB(col,r,g,b);
00209         UCHAR aR = r, aG = g, aB = b, aA = 0;
00210 
00211         glLineWidth(lineW);
00212         glBegin(GL_LINE_STRIP);
00213         for (float i=startFrame; i<endFrame; i+=inc)
00214         {
00215             double sim = (*avgVector)[(int)(i+mFrameError)];
00216             aA = test ? 0 : opaq;
00217             if (test && PassTest(sim,maxim,means))
00218             {
00219                 if (norm)
00220                 {
00221                     float normSim = sim/maxim;
00222                     aR = normSim * r;
00223                     aG = normSim * g;
00224                     aB = normSim * b;
00225                 }
00226                 aA = opaq;
00227             }
00228             glColor4ub(aR,aG,aB,aA);
00229             float x = (float) Unit2Pixel(i*40);
00230             if (hRange)
00231                 lineY = (mAxisY + 2 + sim * hRange);
00232             glVertex2f(x,lineY);
00233         }
00234         glEnd();
00235         oglSys.EndBlend(bInfo);
00236         glLineWidth(1);
00237     }
00238 
00239     virtual void DisplayFunc()
00240     {
00241         OGC myOGC;
00242             OGCSave( &myOGC );
00243 
00244         TimeLineViewStrip::DisplayFunc();
00245 
00246         if (!mSimSet)
00247             return;
00248 
00249         int startFrame = FirstVisibleFrame();
00250         int endFrame   = LastVisibleFrame();
00251 
00252         if (endFrame > mSimSet->TableSize()-mFrameError-1)
00253             endFrame = mSimSet->TableSize()-mFrameError-1;
00254 
00255         int     range   = endFrame - startFrame;
00256         int     lineMax = H() - 4 - ((mAverages&&mShowClassify)?65:0);
00257         int     hRange  = lineMax - mAxisY;
00258         int     inc     = 1;
00259 
00260         if (range >= cMaxVisPerConcept)
00261             inc = (int) ((range / (double)cMaxVisPerConcept)+0.5);
00262 
00263         // Experiment to minimize flutter when sampling
00264         while(startFrame%inc)
00265             startFrame--;
00266 
00267         float bigW = 5;
00268         for (int j=0; j<mSimSet->NrTables(); j++)
00269         {
00270             DrawAverages(j,startFrame,endFrame,inc,true,true,200,0,bigW);
00271             DrawAverages(j,startFrame,endFrame,inc,true,false,255,0,1);
00272 
00273             if (!mVisibleConcepts[j])
00274                 continue;
00275 
00276             DrawAverages(j,startFrame,endFrame,inc,false,false,255,hRange,1);
00277             DrawAverages(j,startFrame,endFrame,inc,true,false,128,hRange,bigW);
00278 
00279             ULONG col = mSimColors[j%mSimColors.size()];
00280             UCHAR r,g,b;
00281             COLOR2RGB(col,r,g,b);
00282             glColor3ub(r,g,b);
00283             SimTableType* simTable = mSimSet->GetSimTable(j);
00284             glPointSize(range < 300 ? (range<100?5:3) : 2);
00285             glBegin(GL_POINTS);
00286             for (float i=startFrame; i<=endFrame; i+=inc)
00287             {
00288                 double sim = simTable->Get1(i+mFrameError);
00289                 float  x   = (float) Unit2Pixel(i*40);
00290                 float  y   = (float) (mAxisY + 2 + sim * hRange);
00291                 glVertex2f(x,y);
00292             }
00293             glEnd();
00294 
00295         }
00296         glPointSize(1);
00297         glLineWidth(1);
00298 
00299         DrawHelpLines(lineMax,hRange);
00300 
00301         NeedleOverConcepts();
00302 
00303         OGCRestore(&myOGC);
00304     }
00305 
00306     virtual void MouseFunc(int msg, int btn, int state, int x, int y)
00307     {
00308         TimeLineViewStrip::MouseFunc(msg,btn,state,x,y);
00309         mHelpLineActive = (state==oglLeftButton);
00310         mHelpLineX = x;
00311         mHelpLineY = y;
00312     }
00313 
00314 private:
00315 
00316     void Init(int w, int h)
00317     {
00318         mListener = 0;
00319         mSimSet = 0;
00320         SetStart(0);
00321         SetSpan(60000);
00322         mCurrentConcept = 0;
00323         mShowClassify = true;
00324         ShowNeedle(false); // We handle the needle ourselves
00325         SetNeedleColor(oglBLACK);
00326         SetNeedleUpDownHeight(1000,4);
00327         mNrColors = 0;
00328         while( sColorNamesSTL[mNrColors][0] != 0 )
00329             mSimColors.push_back(OglColorStr(sColorNamesSTL[mNrColors++]));
00330         mAverages = 0;
00331         mPercMax = 0.66f;
00332         mPercMaxMean = 0.25f;
00333         mHelpLineActive = false;
00334     }
00335 
00336     static const int            cMaxVisPerConcept = 10000;
00337 
00338     SimilarityTimeLineListener* mListener;
00339     void*                       mListenerData;
00340 
00341     SimilarityTableSet*         mSimSet;
00342     std::vector<ULONG>          mSimColors;
00343     std::vector<bool>           mVisibleConcepts;
00344 
00345 Averages* mAverages;
00346 FloatVector* mMaxima;
00347 FloatVector* mMeans;
00348 float       mPercMax;
00349 float       mPercMaxMean;
00350 bool        mShowClassify;
00351 bool        mHelpLineActive;
00352 int         mHelpLineY;
00353 int         mHelpLineX;
00354 
00355     int                         mCurrentConcept;
00356     int                         mNrColors;
00357 };
00358 } // namespace Visualization
00359 } // namespace Impala
00360 #endif

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