Main MRPT website > C++ reference for MRPT 1.5.7
faster_corner_12.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 // ---------------------------------------------------------------------------
11 // LICENSING: This file is a slightly-modified version of part of libcvd,
12 // released under LGPL 2.1 by Edward Rosten
13 // ---------------------------------------------------------------------------
14 
15 #include <mrpt/utils/utils_defs.h>
16 #include <mrpt/system/memory.h>
18 
19 #include <mrpt/utils/SSE_types.h>
21 #include "corner_12.h"
22 
23 using namespace std;
24 using namespace mrpt;
25 using namespace mrpt::utils;
26 
27 
28 template <int I, int N> struct BitCheck
29 {
30  template <class C> static inline void eval(unsigned int three, const uint8_t* p, const int w, const int barrier, C& corners) {
31  const int BIT = 1<<I;
32  if (three & BIT) {
33  if (three & (BIT << 16)) {
34  if (is_corner_12<Greater>(p, w, barrier))
35  corners.push_back(p);
36  } else {
37  if (is_corner_12<Less>(p, w, barrier))
38  corners.push_back(p);
39  }
40  }
41  BitCheck<I+1,N>::eval(three, p+1, w, barrier, corners);
42  }
43 };
44 
45 template <int N> struct BitCheck<N,N>
46 {
47  template <class C> static inline void eval(unsigned int, const uint8_t* , const int , const int , C& ) {}
48 };
49 
50 template <int CHUNKS, class C> inline void process_16(unsigned int three, const uint8_t* p, const int w, const int barrier, C& corners)
51 {
52 three |= (three >> 16);
53 const int BITS = 16/CHUNKS;
54 const int mask = ((1<<BITS)-1);
55 for (int i=0; i<CHUNKS; ++i) {
56  if (three & mask)
57  BitCheck<0,BITS>::eval(three, p, w, barrier, corners);
58  p += BITS;
59  three >>= BITS;
60 }
61 }
62 
63 
64 #if MRPT_HAS_SSE2 && MRPT_HAS_OPENCV
65 
66 template <bool Aligned>
67 void faster_corner_detect_12(const IplImage* I, mrpt::vision::TSimpleFeatureList & corners, int barrier, uint8_t octave, std::vector<size_t> * out_feats_index_by_row)
68 {
69  corners.reserve(corners.size()+500);
70  //corners.mark_kdtree_as_outdated();
71 
72  size_t *ptr_feat_index_by_row, *ptr_feat_index_end;
73  if (out_feats_index_by_row)
74  {
75  out_feats_index_by_row->resize(I->height);
76  ptr_feat_index_by_row = &(*out_feats_index_by_row)[0];
77  ptr_feat_index_end = ptr_feat_index_by_row+out_feats_index_by_row->size();
78  }
79  else {
80  ptr_feat_index_by_row = NULL;
81  ptr_feat_index_end=NULL;
82  }
83 
84 const int w = I->width;
85 const int stride = 3*I->widthStep; // 3*w;
86 typedef std::list<const uint8_t*> Passed;
87 Passed passed;
88 
89 // The compiler refuses to reserve a register for this,
90 // even though xmm6 and xmm7 go unused.
91 // It loads it from memory each time. I am stymied.
92 const __m128i barriers = _mm_set1_epi8((uint8_t)barrier);
93 
94 for (int i=3; i<I->height-3; ++i) {
95  const uint8_t* p = (const uint8_t*)I->imageData + I->widthStep*i; // I[i];
96  for (int j=0; j<w/16; ++j, p+=16) {
97  __m128i lo, hi;
98  {
99  const __m128i here = load_si128<Aligned>((const __m128i*)(p));
100  lo = _mm_subs_epu8(here, barriers);
101  hi = _mm_adds_epu8(barriers, here);
102  }
103  const __m128i above = load_si128<Aligned>((const __m128i*)(p-stride));
104  const __m128i below = load_si128<Aligned>((const __m128i*)(p+stride));
105  unsigned int up_flags, down_flags;
106  CHECK_BARRIER(lo, hi, above, up_flags);
107  CHECK_BARRIER(lo, hi, below, down_flags);
108  const unsigned int either_ud = up_flags | down_flags;
109  if (either_ud) {
110  unsigned int left_flags;
111  {
112  const __m128i other = _mm_loadu_si128((const __m128i*)(p-3));
113  CHECK_BARRIER(lo, hi, other, left_flags);
114  }
115  const unsigned int both_ud = up_flags & down_flags;
116  if (both_ud | (either_ud&left_flags)) {
117  unsigned int right_flags;
118  {
119  const __m128i other = _mm_loadu_si128((const __m128i*)(p+3));
120  CHECK_BARRIER(lo, hi, other, right_flags);
121  }
122  const unsigned int at_least_three = (either_ud & (left_flags & right_flags)) | (both_ud & (left_flags | right_flags));
123  if (at_least_three) {
124  process_16<4>(at_least_three, p, w, barrier, passed);
125  }
126  }
127  }
128  }
129 
130  //Do the edge of the row, using the old-fasioned 4 point test
131  for(int j=(w/16) * 16; j < w-3; j++, p++)
132  {
133  int cb = *p + barrier;
134  int c_b = *p - barrier;
135  int num_above= (p[stride] > cb) + (p[-stride] > cb);
136  int num_below= (p[stride] < c_b) + (p[-stride] < c_b);
137 
138  if(!num_above && !num_below)
139  continue;
140 
141  //Look left
142  num_above+= p[-3] > cb;
143  num_below+= p[-3] < c_b;
144 
145  if(num_above & 2) //num_above is 2 or 3
146  {
147  if(!(num_above & 1)) //num_above is 2
148  num_above += p[3] > cb;
149 
150 
151  //Only do a complete check if num_above is 3
152  if((num_above&1) && is_corner_12<Greater>(p, w, barrier))
153  passed.push_back(p);
154  }
155  else if(num_below & 2)
156  {
157  if(!(num_below & 1))
158  num_below += p[3] < c_b;
159 
160 
161  if((num_below&1) && is_corner_12<Less>(p, w, barrier))
162  passed.push_back(p);
163  }
164  }
165 
166  passed.push_back(0);
167 }
168 
169  // 3 first rows have no features:
170  if (ptr_feat_index_by_row) {
171  *ptr_feat_index_by_row++ = corners.size();
172  *ptr_feat_index_by_row++ = corners.size();
173  *ptr_feat_index_by_row++ = corners.size();
174  }
175 
176  int row = 3;
177 
178  const uint8_t* row_start = (const uint8_t*)I->imageData + I->widthStep*3;
179  for (Passed::iterator it = passed.begin(); it != passed.end(); ++it) {
180  if (*it == 0)
181  {
182  // next row:
183  if (ptr_feat_index_by_row) // save index by row:
184  *ptr_feat_index_by_row++=corners.size();
185 
186  row_start= (const uint8_t*)I->imageData + I->widthStep*(++row); // I[++row];
187  continue;
188  }
189  int x = *it - row_start;
190  if (x > 2 && x < w-3)
191  corners.push_back_fast(x<<octave, row<<octave);
192  }
193 
194  // 3 last rows have no features:
195  if (ptr_feat_index_by_row) {
196  *ptr_feat_index_by_row++ = corners.size();
197  *ptr_feat_index_by_row++ = corners.size();
198  *ptr_feat_index_by_row++ = corners.size();
199  ASSERT_(ptr_feat_index_by_row==ptr_feat_index_end)
200  }
201 
202 }
203 
204 
205 #endif // MRPT_HAS_SSE2 && MRPT_HAS_OPENCV
206 
207 
208 #if MRPT_HAS_OPENCV
209 
210 void fast_corner_detect_12(const IplImage* I, mrpt::vision::TSimpleFeatureList & corners, int barrier, uint8_t octave, std::vector<size_t> * out_feats_index_by_row)
211 {
212  if (I->width < 22)
213  {
214  fast_corner_detect_plain_12(I,corners,barrier, octave,out_feats_index_by_row);
215  return;
216  }
217  else if (I->width < 22 || I->height < 7)
218  return;
219 
220 #if MRPT_HAS_SSE2
221  if (mrpt::system::is_aligned<16>(I->imageData) && mrpt::system::is_aligned<16>(I->imageData+I->widthStep))
222  faster_corner_detect_12<true>(I, corners, barrier, octave,out_feats_index_by_row);
223  else
224  faster_corner_detect_12<false>(I, corners, barrier, octave,out_feats_index_by_row);
225 #else
226  fast_corner_detect_plain_12(I,corners,barrier, octave,out_feats_index_by_row);
227 #endif
228 }
229 #endif
bool is_aligned< 16 >(const void *ptr)
Definition: memory.h:107
GLenum GLint GLuint mask
Definition: glext.h:3888
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
void fast_corner_detect_12(const IplImage *I, mrpt::vision::TSimpleFeatureList &corners, int barrier, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
void fast_corner_detect_plain_12(const IplImage *i, TSimpleFeatureList &corners, int b, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
Scalar * iterator
Definition: eigen_plugins.h:23
static void eval(unsigned int three, const uint8_t *p, const int w, const int barrier, C &corners)
STL namespace.
#define CHECK_BARRIER(lo, hi, other, flags)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3962
unsigned char uint8_t
Definition: rptypes.h:43
GLsizei stride
Definition: glext.h:3702
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
static void eval(unsigned int, const uint8_t *, const int, const int, C &)
GLenum GLenum GLvoid * row
Definition: glext.h:3533
void faster_corner_detect_12(const IplImage *I, mrpt::vision::TSimpleFeatureList &corners, int barrier, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
#define ASSERT_(f)
GLenum GLint x
Definition: glext.h:3516
GLfloat GLfloat p
Definition: glext.h:5587
void process_16(unsigned int three, const uint8_t *p, const int w, const int barrier, C &corners)



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019