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.
nonmax_suppression.cpp
Go to the documentation of this file.
1 #include "image_ref.h"
2 #include "nonmax_suppression.h"
3 #include <vector>
4 
5 using namespace std;
6 
7 namespace CVD
8 {
9 
10 
11 //This function has been moved from fast_corner.cxx. Look there
12 //for the old ChangeLog.
13 // fast_nonmax_t is templated so you can have either of:
14 // 1: A vector of ImageRefs of the nonmax corners
15 // 2: A vector of <ImageRef, int> pairs of the corners and their scores.
16 // And
17 // 1: Non-strict (neighbours of the same score allowed)
18 // 2: Strict (must be larger than the neighbours)
19 // It's internal, the user-visible functions instantiate it below..
20 template<class Score, class ReturnType, class Collector, class Test>
21 inline void nonmax_suppression_t(const vector<ImageRef>& corners, const vector<Score>& scores, vector<ReturnType>& nonmax_corners)
22 {
23  nonmax_corners.clear();
24  nonmax_corners.reserve(corners.size());
25 
26  if(corners.size() < 1)
27  return;
28 
29 
30  // Find where each row begins
31  // (the corners are output in raster scan order). A beginning of -1 signifies
32  // that there are no corners on that row.
33  int last_row = corners.back().y;
34  vector<int> row_start(last_row + 1, -1);
35 
36  int prev_row = -1;
37  for(unsigned int i=0; i< corners.size(); i++)
38  if(corners[i].y != prev_row)
39  {
40  row_start[corners[i].y] = i;
41  prev_row = corners[i].y;
42  }
43 
44 
45  //Point above points (roughly) to the pixel above the one of interest, if there
46  //is a feature there.
47  int point_above = 0;
48  int point_below = 0;
49 
50  const int sz = (int)corners.size();
51 
52  for(int i=0; i < sz; i++)
53  {
54  Score score = scores[i];
55  ImageRef pos = corners[i];
56 
57  //Check left
58  if(i > 0)
59  if(corners[i-1] == pos-ImageRef(1,0) && Test::Compare(scores[i-1], score))
60  continue;
61 
62  //Check right
63  if(i < (sz - 1))
64  if(corners[i+1] == pos+ImageRef(1,0) && Test::Compare(scores[i+1], score))
65  continue;
66 
67  //Check above (if there is a valid row above)
68  if(pos.y != 0 && row_start[pos.y - 1] != -1)
69  {
70  //Make sure that current point_above is one
71  //row above.
72  if(corners[point_above].y < pos.y - 1)
73  point_above = row_start[pos.y-1];
74 
75  //Make point_above point to the first of the pixels above the current point,
76  //if it exists.
77  for(; corners[point_above].y < pos.y && corners[point_above].x < pos.x - 1; point_above++)
78  {}
79 
80 
81  for(int i=point_above; corners[i].y < pos.y && corners[i].x <= pos.x + 1; i++)
82  {
83  int x = corners[i].x;
84  if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Test::Compare(scores[i], score))
85  goto cont;
86  }
87 
88  }
89 
90  //Check below (if there is anything below)
91  if(pos.y != last_row && row_start[pos.y + 1] != -1 && point_below < sz) //Nothing below
92  {
93  if(corners[point_below].y < pos.y + 1)
94  point_below = row_start[pos.y+1];
95 
96  // Make point below point to one of the pixels belowthe current point, if it
97  // exists.
98  for(; point_below < sz && corners[point_below].y == pos.y+1 && corners[point_below].x < pos.x - 1; point_below++)
99  {}
100 
101  for(int i=point_below; i < sz && corners[i].y == pos.y+1 && corners[i].x <= pos.x + 1; i++)
102  {
103  int x = corners[i].x;
104  if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Test::Compare(scores[i],score))
105  goto cont;
106  }
107  }
108 
109  nonmax_corners.push_back(Collector::collect(corners[i],scores[i]));
110 
111  cont:
112  ;
113  }
114 }
115 
116 
117 struct Greater
118 {
119  static bool Compare(int a, int b)
120  {
121  return a > b;
122  }
123 };
124 
126 {
127  static bool Compare(int a, int b)
128  {
129  return a >= b;
130  }
131 };
132 
133 // The two collectors which either return just the ImageRef or the <ImageRef,int> pair
135 {
136  static inline ImageRef collect(const ImageRef& pos, int ){return pos;}
137 };
138 
140 {
141  static inline pair<ImageRef, int> collect(const ImageRef& pos, int score){return make_pair(pos,score);}
142 };
143 
144 // The callable functions
145 void nonmax_suppression_strict(const vector<ImageRef>& corners, const vector<int>& scores, vector<ImageRef>& nonmax_corners)
146 {
147  nonmax_suppression_t<int, ImageRef, collect_pos, GreaterEqual>(corners, scores, nonmax_corners);
148 }
149 
150 void nonmax_suppression(const vector<ImageRef>& corners, const vector<int>& scores, vector<ImageRef>& nonmax_corners)
151 {
152  nonmax_suppression_t<int, ImageRef, collect_pos, Greater>(corners, scores, nonmax_corners);
153 }
154 
155 void nonmax_suppression_with_scores(const vector<ImageRef>& corners, const vector<int>& scores, vector<pair<ImageRef,int> >& nonmax_corners)
156 {
157  nonmax_suppression_t<int, pair<ImageRef,int> , collect_score, Greater>(corners, scores, nonmax_corners);
158 }
159 
160 
161 }
void nonmax_suppression_with_scores(const vector< ImageRef > &corners, const vector< int > &scores, vector< pair< ImageRef, int > > &nonmax_corners)
int y
The y co-ordinate.
Definition: image_ref.h:180
int x
The x co-ordinate.
Definition: image_ref.h:179
Definition: abs.h:24
static pair< ImageRef, int > collect(const ImageRef &pos, int score)
void nonmax_suppression_t(const vector< ImageRef > &corners, const vector< Score > &scores, vector< ReturnType > &nonmax_corners)
static bool Compare(int a, int b)
void nonmax_suppression(const vector< ImageRef > &corners, const vector< int > &scores, vector< ImageRef > &nonmax_corners)
static bool Compare(int a, int b)
void nonmax_suppression_strict(const vector< ImageRef > &corners, const vector< int > &scores, vector< ImageRef > &nonmax_corners)
static ImageRef collect(const ImageRef &pos, int)