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.
PatchFinder.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 // Copyright 2008 Isis Innovation Limited
3 //
4 // This header declares the PatchFinder class.
5 // This is quite a low-level class.
6 //
7 // The purpose of the PatchFinder is to find a map point in a new view.
8 // This proceeds in multiple stages:
9 // 1. A warping matrix appropriate for the current view is calculated,
10 // 2. A `coarse' matching template of the map point is generated by warping;
11 // 3. The new view is searched for this template at corner locations;
12 // 4. An inverse-composition (`fine') matching template is generated;
13 // 5. A sub-pixel accurate position is calculated using inverse composition.
14 //
15 // To clarify points 1 and 2 above: Each map point does _not_ store a `patch'
16 // in the style of many other SLAM implementations! Each map point came from
17 // a key-frame, and that key-frame is stored in the map. Each map point only
18 // stores the information on where it came from in what key-frame. Patches
19 // are then generated from the pixels of the source key-frame. According to the
20 // relative camera poses now and of the source key-frame, a warp has to be
21 // applied to generate an NxN pixel square template appropriate for the current
22 // view. Thus, the matching template is always NxN, but the region of source
23 // pixels used can change size and shape! This is all described in the
24 // Klein & Murray ISMAR 2007.
25 //
26 // Most of the above stages are optional, and there are different versions
27 // of stages 1/2, including some for operating when there is not yet a 3D map
28 // point. The class provides no safety checks to ensure that the operations
29 // are carried out in the right order - it's the caller's responsibility.
30 //
31 // The patch finder uses zero-mean SSD as its difference metric.
32 //
33 // Although PatchFinder can use arbitrary-sized search templates (it's determined
34 // at construction), the use of 8x8 pixel templates (the default) is highly
35 // recommended, as the coarse search for this size is SSE-optimised.
36 
37 #ifndef __PATCHFINDER_H
38 #define __PATCHFINDER_H
39 
40 #include "TooN.h"
41 using namespace TooN;
42 #include "se3.h"
43 #include "image.h"
44 #include "byte.h"
45 #include "MapPoint.h"
46 #include "LevelHelpers.h"
47 #include "globals.h"
48 
50 {
51 public:
52  // Constructor defines size of search patch.
53  PatchFinder(int nPatchSize = 8);
54 
55  // Step 1 Function.
56  // This calculates the warping matrix appropriate for observing point p
57  // from the current view (described as an SE3.) This also needs the camera
58  // projection derivates at level zero for the point's projection in the new view.
59  // It also calculates which pyramid level we should search in, and this is
60  // returned as an int. Negative level returned denotes an inappropriate
61  // transformation.
62  int CalcSearchLevelAndWarpMatrix(MapPoint &p, SE3<> se3CFromW, Matrix<2> &m2CamDerivs);
63  inline int GetLevel() { return mnSearchLevel; }
64  inline int GetLevelScale() { return LevelScale(mnSearchLevel); }
65 
66  // Step 2 Functions
67  // Generates the NxN search template either from the pre-calculated warping matrix,
68  // or an identity transformation.
69  void MakeTemplateCoarseCont(MapPoint &p); // If the warping matrix has already been pre-calced, use this.
70  void MakeTemplateCoarse(MapPoint &p, SE3<> se3CFromW, Matrix<2> &m2CamDerivs); // This also calculates the warp.
71  void MakeTemplateCoarseNoWarp(MapPoint &p); // Identity warp: just copies pixels from the source KF.
72  void MakeTemplateCoarseNoWarp(KeyFrame &k, int nLevel, CVD::ImageRef irLevelPos); // Identity warp if no MapPoint struct exists yet.
73 
74  // If the template making failed (i.e. it needed pixels outside the source image),
75  // this bool will return false.
76  inline bool TemplateBad() { return mbTemplateBad;}
77 
78  // Step 3 Functions
79  // This is the raison d'etre of the class: finds the patch in the current input view,
80  // centered around ir, Searching around FAST corner locations only within a radius nRange only.
81  // Inputs are given in level-zero coordinates! Returns true if the patch was found.
82  bool FindPatchCoarse(CVD::ImageRef ir, KeyFrame &kf, unsigned int nRange);
83  int ZMSSDAtPoint(CVD::BasicImage<CVD::byte> &im, const CVD::ImageRef &ir); // This evaluates the score at one location
84  // Results from step 3:
85  // All positions are in the scale of level 0.
86  inline CVD::ImageRef GetCoarsePos() { return CVD::ImageRef((int) mv2CoarsePos[0], (int) mv2CoarsePos[1]);}
87  inline Vector<2> GetCoarsePosAsVector() { return mv2CoarsePos; }
88 
89  // Step 4
90  void MakeSubPixTemplate(); // Generate the inverse composition template and jacobians
91 
92  // Step 5 Functions
93  bool IterateSubPixToConvergence(KeyFrame &kf, int nMaxIts); // Run inverse composition till convergence
94  double IterateSubPix(KeyFrame &kf); // Single iteration of IC. Returns sum-squared pixel update dist, or negative if out of imag
95  inline Vector<2> GetSubPixPos() { return mv2SubPixPos; } // Get result
96  void SetSubPixPos(Vector<2> v2) { mv2SubPixPos = v2; } // Set starting point
97 
98  // Get the uncertainty estimate of a found patch;
99  // This for just returns an appropriately-scaled identity!
100  inline Matrix<2> GetCov()
101  {
102  return LevelScale(mnSearchLevel) * Identity;
103  };
104 
105  int mnMaxSSD; // This is the max ZMSSD for a valid match. It's set in the constructor.
106 
107 protected:
108 
109  int mnPatchSize; // Size of one side of the matching template.
110 
111  // Some values stored for the coarse template:
112  int mnTemplateSum; // Cached pixel-sum of the coarse template
113  int mnTemplateSumSq; // Cached pixel-squared sum of the coarse template
114  inline void MakeTemplateSums(); // Calculate above values
115 
116  CVD::Image<CVD::byte> mimTemplate; // The matching template
117  CVD::Image<std::pair<float,float> > mimJacs; // Inverse composition jacobians; stored as floats to save a bit of space.
118 
119  Matrix<2> mm2WarpInverse; // Warping matrix
120  int mnSearchLevel; // Search level in input pyramid
121  Matrix<3> mm3HInv; // Inverse composition JtJ^-1
122  Vector<2> mv2SubPixPos; // In the scale of level 0
123  double mdMeanDiff; // Updated during inverse composition
124 
125  CVD::ImageRef mirPredictedPos; // Search center location of FindPatchCoarse in L0
126  Vector<2> mv2CoarsePos; // In the scale of level 0; hence the use of vector rather than ImageRef
127  CVD::ImageRef mirCenter; // Quantized location of the center pixel of the NxN pixel template
128  bool mbFound; // Was the patch found?
129  bool mbTemplateBad; // Error during template generation?
130 
131  // Some cached values to avoid duplicating work if the camera is stopped:
132  MapPoint *mpLastTemplateMapPoint; // Which was the last map point this PatchFinder used?
133  Matrix<2> mm2LastWarpMatrix; // What was the last warp matrix this PatchFinder used?
134 };
135 
136 #endif
137 
138 
139 
140 
141 
142 
143 
144 
Vector< 2 > mv2SubPixPos
Definition: PatchFinder.h:122
Matrix< 2 > mm2LastWarpMatrix
Definition: PatchFinder.h:133
int LevelScale(int nLevel)
Definition: LevelHelpers.h:20
static Operator< Internal::Identity< Internal::One > > Identity
Definition: objects.h:748
int GetLevel()
Definition: PatchFinder.h:63
CVD::ImageRef mirPredictedPos
Definition: PatchFinder.h:125
int mnTemplateSum
Definition: PatchFinder.h:112
Vector< 2 > mv2CoarsePos
Definition: PatchFinder.h:126
double mdMeanDiff
Definition: PatchFinder.h:123
Everything lives inside this namespace.
Definition: allocator.hh:48
CVD::Image< std::pair< float, float > > mimJacs
Definition: PatchFinder.h:117
void SetSubPixPos(Vector< 2 > v2)
Definition: PatchFinder.h:96
Matrix< 3 > mm3HInv
Definition: PatchFinder.h:121
Vector< 2 > GetSubPixPos()
Definition: PatchFinder.h:95
CVD::ImageRef mirCenter
Definition: PatchFinder.h:127
Vector< 2 > GetCoarsePosAsVector()
Definition: PatchFinder.h:87
bool TemplateBad()
Definition: PatchFinder.h:76
Definition: se3.h:50
CVD::Image< CVD::byte > mimTemplate
Definition: PatchFinder.h:116
Matrix< 2 > GetCov()
Definition: PatchFinder.h:100
int mnSearchLevel
Definition: PatchFinder.h:120
Matrix< 2 > mm2WarpInverse
Definition: PatchFinder.h:119
bool mbTemplateBad
Definition: PatchFinder.h:129
ImageRef ir(const TooN::Vector< 2 > &v)
CVD::ImageRef GetCoarsePos()
Definition: PatchFinder.h:86
int GetLevelScale()
Definition: PatchFinder.h:64
MapPoint * mpLastTemplateMapPoint
Definition: PatchFinder.h:132
int mnTemplateSumSq
Definition: PatchFinder.h:113