KeyFrame.cc
Go to the documentation of this file.
00001 // Copyright 2008 Isis Innovation Limited
00002 #include "KeyFrame.h"
00003 #include "ShiTomasi.h"
00004 #include "SmallBlurryImage.h"
00005 #include <cvd/vision.h>
00006 #include <cvd/fast_corner.h>
00007 
00008 #include "settingsCustom.h"
00009 
00010 using namespace CVD;
00011 using namespace std;
00012 using namespace GVars3;
00013 
00014 void KeyFrame::MakeKeyFrame_Lite(BasicImage<byte> &im)
00015 {
00016   // Perpares a Keyframe from an image. Generates pyramid levels, does FAST detection, etc.
00017   // Does not fully populate the keyframe struct, but only does the bits needed for the tracker;
00018   // e.g. does not perform FAST nonmax suppression. Things like that which are needed by the 
00019   // mapmaker but not the tracker go in MakeKeyFrame_Rest();
00020   
00021   // First, copy out the image data to the pyramid's zero level.
00022   aLevels[0].im.resize(im.size());
00023   copy(im, aLevels[0].im);
00024 
00025   // Then, for each level...
00026   for(int i=0; i<LEVELS; i++)
00027     {
00028       Level &lev = aLevels[i];
00029       if(i!=0)
00030         {  // .. make a half-size image from the previous level..
00031           lev.im.resize(aLevels[i-1].im.size() / 2);
00032           halfSample(aLevels[i-1].im, lev.im);
00033         }
00034       
00035       // .. and detect and store FAST corner points.
00036       // I use a different threshold on each level; this is a bit of a hack
00037       // whose aim is to balance the different levels' relative feature densities.
00038       lev.vCorners.clear();
00039       lev.vCandidates.clear();
00040       lev.vMaxCorners.clear();
00041       if(i == 0)
00042         fast_corner_detect_10(lev.im, lev.vCorners, 10);
00043       if(i == 1)
00044         fast_corner_detect_10(lev.im, lev.vCorners, 15);
00045       if(i == 2)
00046         fast_corner_detect_10(lev.im, lev.vCorners, 15);
00047       if(i == 3)
00048         fast_corner_detect_10(lev.im, lev.vCorners, 10);
00049       
00050       // Generate row look-up-table for the FAST corner points: this speeds up 
00051       // finding close-by corner points later on.
00052       unsigned int v=0;
00053       lev.vCornerRowLUT.clear();
00054       for(int y=0; y<lev.im.size().y; y++)
00055         {
00056           while(v < lev.vCorners.size() && y > lev.vCorners[v].y)
00057             v++;
00058           lev.vCornerRowLUT.push_back(v);
00059         }
00060     };
00061 }
00062 
00063 void KeyFrame::MakeKeyFrame_Rest()
00064 {
00065   // Fills the rest of the keyframe structure needed by the mapmaker:
00066   // FAST nonmax suppression, generation of the list of candidates for further map points,
00067   // creation of the relocaliser's SmallBlurryImage.
00068   static gvar3<double> gvdCandidateMinSTScore("MapMaker.CandidateMinShiTomasiScore", MAPMAKER_MIN_SHI_THOMASI_SCORE, SILENT);
00069   
00070   // For each level...
00071   for(int l=0; l<LEVELS; l++)
00072     {
00073       Level &lev = aLevels[l];
00074       // .. find those FAST corners which are maximal..
00075       fast_nonmax(lev.im, lev.vCorners, 10, lev.vMaxCorners);
00076       // .. and then calculate the Shi-Tomasi scores of those, and keep the ones with
00077       // a suitably high score as Candidates, i.e. points which the mapmaker will attempt
00078       // to make new map points out of.
00079       for(vector<ImageRef>::iterator i=lev.vMaxCorners.begin(); i!=lev.vMaxCorners.end(); i++)
00080         {
00081           if(!lev.im.in_image_with_border(*i, 10))
00082             continue;
00083           double dSTScore = FindShiTomasiScoreAtPoint(lev.im, 3, *i);
00084           if(dSTScore > *gvdCandidateMinSTScore)
00085             {
00086               Candidate c;
00087               c.irLevelPos = *i;
00088               c.dSTScore = dSTScore;
00089               lev.vCandidates.push_back(c);
00090             }
00091         }
00092     };
00093   
00094   // Also, make a SmallBlurryImage of the keyframe: The relocaliser uses these.
00095   pSBI = new SmallBlurryImage(*this);  
00096   // Relocaliser also wants the jacobians..
00097   pSBI->MakeJacs();
00098 }
00099 
00100 // The keyframe struct is quite happy with default operator=, but Level needs its own
00101 // to override CVD's reference-counting behaviour.
00102 Level& Level::operator=(const Level &rhs)
00103 {
00104   // Operator= should physically copy pixels, not use CVD's reference-counting image copy.
00105   im.resize(rhs.im.size());
00106   copy(rhs.im, im);
00107   
00108   vCorners = rhs.vCorners;
00109   vMaxCorners = rhs.vMaxCorners;
00110   vCornerRowLUT = rhs.vCornerRowLUT;
00111   return *this;
00112 }
00113 
00114 // -------------------------------------------------------------
00115 // Some useful globals defined in LevelHelpers.h live here:
00116 Vector<3> gavLevelColors[LEVELS];
00117 
00118 // These globals are filled in here. A single static instance of this struct is run before main()
00119 struct LevelHelpersFiller // Code which should be initialised on init goes here; this runs before main()
00120 {
00121   LevelHelpersFiller()
00122   {
00123     for(int i=0; i<LEVELS; i++)
00124       {
00125         if(i==0)  gavLevelColors[i] = makeVector( 1.0, 0.0, 0.0);
00126         else if(i==1)  gavLevelColors[i] = makeVector( 1.0, 1.0, 0.0);
00127         else if(i==2)  gavLevelColors[i] = makeVector( 0.0, 1.0, 0.0);
00128         else if(i==3)  gavLevelColors[i] = makeVector( 0.0, 0.0, 0.7);
00129         else gavLevelColors[i] =  makeVector( 1.0, 1.0, 0.7); // In case I ever run with LEVELS > 4
00130       }
00131   }
00132 };
00133 static LevelHelpersFiller foo;
00134 
00135 
00136 
00137 
00138 
00139 
00140 


tum_ardrone
Author(s):
autogenerated on Sat Jun 8 2019 20:27:23