SLAMflex SE  0.1.0
SLAMflex provides detection and tracking of dominant planes for smartphone devices. This plane can then be used to show AR content relative to the plane orientation. The detection of plane is performed in the field of view of the smartphone camera. In subsequent frames it is tracked. The interface returns the plane position and orientation.
KeyFrame.cpp
Go to the documentation of this file.
1 // Copyright 2008 Isis Innovation Limited
2 #include "KeyFrame.h"
3 #include "ShiTomasi.h"
4 #include "SmallBlurryImage.h"
5 #include "vision.h"
6 #include "fast_corner.h"
7 
8 using namespace CVD;
9 using namespace std;
10 
11 
13 {
14  // Perpares a Keyframe from an image. Generates pyramid levels, does FAST detection, etc.
15  // Does not fully populate the keyframe struct, but only does the bits needed for the tracker;
16  // e.g. does not perform FAST nonmax suppression. Things like that which are needed by the
17  // mapmaker but not the tracker go in MakeKeyFrame_Rest();
18 
19  // First, copy out the image data to the pyramid's zero level.
20  aLevels[0].im.resize(im.size());
21  copy(im, aLevels[0].im);
22 
23  int retVal = 0;
24 
25 
26  // Then, for each level...
27  for(int i=0; i<LEVELS; i++)
28  {
29  Level &lev = aLevels[i];
30  if(i!=0)
31  { // .. make a half-size image from the previous level..
32  lev.im.resize(aLevels[i-1].im.size() / 2);
33  halfSample(aLevels[i-1].im, lev.im);
34  }
35 
36  // .. and detect and store FAST corner points.
37  // I use a different threshold on each level; this is a bit of a hack
38  // whose aim is to balance the different levels' relative feature densities.
39  lev.vCorners.clear();
40  lev.vCandidates.clear();
41  lev.vMaxCorners.clear();
42  if(i == 0)
43  {
44  fast_corner_detect_10(lev.im, lev.vCorners, threshold);
45  retVal = lev.vCorners.size();
46  }
47  if(i == 1)
48  fast_corner_detect_10(lev.im, lev.vCorners, threshold+5);
49  if(i == 2)
50  fast_corner_detect_10(lev.im, lev.vCorners, threshold+5);
51  if(i == 3)
52  fast_corner_detect_10(lev.im, lev.vCorners, threshold);
53 
54  // Generate row look-up-table for the FAST corner points: this speeds up
55  // finding close-by corner points later on.
56  unsigned int v=0;
57  lev.vCornerRowLUT.clear();
58  for(int y=0; y<lev.im.size().y; y++)
59  {
60  while(v < lev.vCorners.size() && y > lev.vCorners[v].y)
61  v++;
62  lev.vCornerRowLUT.push_back(v);
63  }
64  };
65 
66  return retVal;
67 }
68 
70 {
71  // Fills the rest of the keyframe structure needed by the mapmaker:
72  // FAST nonmax suppression, generation of the list of candidates for further map points,
73  // creation of the relocaliser's SmallBlurryImage.
74  static double gvdCandidateMinSTScore=MapMakerCandidateMinShiTomasiScore;
75 
76  // For each level...
77  for(int l=0; l<LEVELS; l++)
78  {
79  Level &lev = aLevels[l];
80  // .. find those FAST corners which are maximal..
81  fast_nonmax(lev.im, lev.vCorners, 10, lev.vMaxCorners);
82  // .. and then calculate the Shi-Tomasi scores of those, and keep the ones with
83  // a suitably high score as Candidates, i.e. points which the mapmaker will attempt
84  // to make new map points out of.
85  for(vector<ImageRef>::iterator i=lev.vMaxCorners.begin(); i!=lev.vMaxCorners.end(); i++)
86  {
87  if(!lev.im.in_image_with_border(*i, 10))
88  continue;
89  double dSTScore = FindShiTomasiScoreAtPoint(lev.im, 3, *i);
90  if(dSTScore > gvdCandidateMinSTScore)
91  {
92  Candidate c;
93  c.irLevelPos = *i;
94  c.dSTScore = dSTScore;
95  lev.vCandidates.push_back(c);
96  }
97  }
98  };
99 
100  // Also, make a SmallBlurryImage of the keyframe: The relocaliser uses these.
101  pSBI = new SmallBlurryImage(*this);
102  // Relocaliser also wants the jacobians..
103  pSBI->MakeJacs();
104 }
105 
106 // The keyframe struct is quite happy with default operator=, but Level needs its own
107 // to override CVD's reference-counting behaviour.
109 {
110  // Operator= should physically copy pixels, not use CVD's reference-counting image copy.
111  im.resize(rhs.im.size());
112  copy(rhs.im, im);
113 
114  vCorners = rhs.vCorners;
115  vMaxCorners = rhs.vMaxCorners;
116  vCornerRowLUT = rhs.vCornerRowLUT;
117  return *this;
118 }
119 
120 // -------------------------------------------------------------
121 // Some useful globals defined in LevelHelpers.h live here:
123 
124 // These globals are filled in here. A single static instance of this struct is run before main()
125 struct LevelHelpersFiller // Code which should be initialised on init goes here; this runs before main()
126 {
128  {
129  for(int i=0; i<LEVELS; i++)
130  {
131  if(i==0) gavLevelColors[i] = makeVector( 1.0, 0.0, 0.0);
132  else if(i==1) gavLevelColors[i] = makeVector( 1.0, 1.0, 0.0);
133  else if(i==2) gavLevelColors[i] = makeVector( 0.0, 1.0, 0.0);
134  else if(i==3) gavLevelColors[i] = makeVector( 0.0, 0.0, 0.7);
135  else gavLevelColors[i] = makeVector( 1.0, 1.0, 0.7); // In case I ever run with LEVELS > 4
136  }
137  }
138 };
140 
141 
142 
143 
144 
145 
146 
int y
The y co-ordinate.
Definition: image_ref.h:180
void halfSample(const BasicImage< T > &in, BasicImage< T > &out)
Definition: vision.h:103
static LevelHelpersFiller foo
Definition: KeyFrame.cpp:139
void resize(const ImageRef &size)
Definition: image.h:749
#define LEVELS
Definition: KeyFrame.h:33
double FindShiTomasiScoreAtPoint(BasicImage< byte > &image, int nHalfBoxSize, ImageRef irCenter)
Definition: ShiTomasi.cpp:7
CVD::Image< CVD::byte > im
Definition: KeyFrame.h:59
Definition: abs.h:24
void copy(const BasicImage< S > &in, BasicImage< T > &out, ImageRef size=ImageRef(-1,-1), ImageRef begin=ImageRef(), ImageRef dst=ImageRef())
Definition: utility.h:26
const double MapMakerCandidateMinShiTomasiScore
Definition: globals.h:43
int MakeKeyFrame_Lite(CVD::BasicImage< CVD::byte > &im, int threshold)
Definition: KeyFrame.cpp:12
std::vector< CVD::ImageRef > vCorners
Definition: KeyFrame.h:62
void MakeKeyFrame_Rest()
Definition: KeyFrame.cpp:69
void fast_nonmax(const BasicImage< byte > &im, const vector< ImageRef > &corners, int barrier, vector< ImageRef > &max_corners)
Definition: fast_corner.cpp:83
void threshold(BasicImage< T > &im, const T &minimum, const T &hi)
Definition: vision.h:163
Definition: KeyFrame.h:54
ImageRef size() const
What is the size of this image?
Definition: image.h:370
bool in_image_with_border(const ImageRef &ir, int border) const
Definition: image.h:271
std::vector< int > vCornerRowLUT
Definition: KeyFrame.h:63
Vector< 1 > makeVector(double x1)
Definition: make_vector.hh:4
void fast_corner_detect_10(const BasicImage< byte > &im, std::vector< ImageRef > &corners, int barrier)
std::vector< CVD::ImageRef > vMaxCorners
Definition: KeyFrame.h:64
double dSTScore
Definition: KeyFrame.h:40
std::vector< Candidate > vCandidates
Definition: KeyFrame.h:67
Level & operator=(const Level &rhs)
Definition: KeyFrame.cpp:108
CVD::ImageRef irLevelPos
Definition: KeyFrame.h:38
Vector< 3, float > gavLevelColors[LEVELS]
Definition: KeyFrame.cpp:122