Main MRPT website > C++ reference for MRPT 1.9.9
faster_corner_10.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_10.h"
22 
23 using namespace std;
24 using namespace mrpt;
25 using namespace mrpt::utils;
26 
27 #if MRPT_HAS_SSE2 && MRPT_HAS_OPENCV
28 
29 template <bool Aligned>
31  const IplImage* I, mrpt::vision::TSimpleFeatureList& corners, int barrier,
32  uint8_t octave, std::vector<size_t>* out_feats_index_by_row)
33 {
34  MRPT_UNUSED_PARAM(octave);
35  corners.reserve(corners.size() + 500);
36  // corners.mark_kdtree_as_outdated();
37 
38  size_t* ptr_feat_index_by_row;
39  if (out_feats_index_by_row)
40  {
41  out_feats_index_by_row->resize(I->height);
42  ptr_feat_index_by_row = &(*out_feats_index_by_row)[0];
43  }
44  else
45  {
46  ptr_feat_index_by_row = nullptr;
47  }
48 
49  // 3 first rows have no features:
50  if (ptr_feat_index_by_row)
51  {
52  *ptr_feat_index_by_row++ = corners.size();
53  *ptr_feat_index_by_row++ = corners.size();
54  *ptr_feat_index_by_row++ = corners.size();
55  }
56 
57  const int w = I->width;
58  const int stride = 3 * I->widthStep; // 3*w;
59 
60  // The compiler refuses to reserve a register for this
61  const __m128i barriers = _mm_set1_epi8((uint8_t)barrier);
62 
63  int xend = I->width - 3;
64  xend -= (I->width - 3) % 16;
65 
66  for (int y = 3; y < I->height - 3; y++)
67  {
68  if (ptr_feat_index_by_row) // save index by row:
69  *ptr_feat_index_by_row++ = corners.size();
70 
71  for (int x = 3; x < 16; x++)
72  if (is_corner_10<Less>(
73  (const uint8_t*)I->imageData + I->widthStep * y + x,
74  I->widthStep, barrier) ||
75  is_corner_10<Greater>(
76  (const uint8_t*)I->imageData + I->widthStep * y + x,
77  I->widthStep, barrier))
78  corners.push_back_fast(x, y);
79 
80  for (int x = 16; x < xend; x += 16)
81  {
82  const uint8_t* p =
83  (const uint8_t*)I->imageData + I->widthStep * y + x;
84  __m128i lo, hi;
85  {
86  const __m128i here = load_si128<Aligned>((const __m128i*)(p));
87  lo = _mm_subs_epu8(here, barriers);
88  hi = _mm_adds_epu8(barriers, here);
89  }
90  unsigned int ans_b, ans_e;
91  {
92  __m128i top = load_si128<Aligned>((const __m128i*)(p - stride));
93  __m128i bottom =
94  load_si128<Aligned>((const __m128i*)(p + stride));
95 
96  CHECK_BARRIER(lo, hi, top, ans_b);
97  CHECK_BARRIER(lo, hi, bottom, ans_e);
98  if (!(ans_b | ans_e)) continue;
99  }
100 
101  unsigned int ans_m, ans_p, possible;
102  {
103  __m128i ul = _mm_loadu_si128((const __m128i*)(p - 2 - 2 * w));
104  __m128i lr = _mm_loadu_si128((const __m128i*)(p + 2 + 2 * w));
105  CHECK_BARRIER(lo, hi, ul, ans_m);
106  CHECK_BARRIER(lo, hi, lr, ans_p);
107  possible = (ans_m & ans_b) | (ans_e & ans_p);
108  if (!possible) continue;
109  }
110 
111  unsigned int ans_o, ans_n;
112  {
113  __m128i ll = _mm_loadu_si128((const __m128i*)(p - 2 + 2 * w));
114  __m128i ur = _mm_loadu_si128((const __m128i*)(p + 2 - 2 * w));
115  CHECK_BARRIER(lo, hi, ll, ans_o);
116  CHECK_BARRIER(lo, hi, ur, ans_n);
117  possible &= ans_o | (ans_b & ans_n);
118  possible &= ans_n | (ans_e & ans_o);
119  if (!possible) continue;
120  }
121 
122  unsigned int ans_h, ans_k;
123  {
124  __m128i left = _mm_loadu_si128((const __m128i*)(p - 3));
125  __m128i right = _mm_loadu_si128((const __m128i*)(p + 3));
126  CHECK_BARRIER(lo, hi, left, ans_h);
127  CHECK_BARRIER(lo, hi, right, ans_k);
128  possible &= ans_h | (ans_n & ans_k & ans_p);
129  possible &= ans_k | (ans_m & ans_h & ans_o);
130  if (!possible) continue;
131  }
132 
133  unsigned int ans_a, ans_c;
134  {
135  __m128i a = _mm_loadu_si128((const __m128i*)(p - 1 - stride));
136  __m128i c = _mm_insert_epi16(
137  _mm_srli_si128(a, 2),
138  *(const unsigned short*)(p + 15 - stride), 7);
139  //__m128i c = _mm_loadu_si128((const __m128i*)(p+1-stride));
140  CHECK_BARRIER(lo, hi, a, ans_a);
141  CHECK_BARRIER(lo, hi, c, ans_c);
142  possible &= ans_a | (ans_e & ans_p);
143  possible &= ans_c | (ans_o & ans_e);
144  if (!possible) continue;
145  }
146 
147  unsigned int ans_d, ans_f;
148  {
149  __m128i d = _mm_loadu_si128((const __m128i*)(p - 1 + stride));
150  __m128i f = _mm_insert_epi16(
151  _mm_srli_si128(d, 2),
152  *(const unsigned short*)(p + 15 + stride), 7);
153  //__m128i f = _mm_loadu_si128((const __m128i*)(p+1+stride));
154  CHECK_BARRIER(lo, hi, d, ans_d);
155  CHECK_BARRIER(lo, hi, f, ans_f);
156  const unsigned int ans_abc = ans_a & ans_b & ans_c;
157  possible &= ans_d | (ans_abc & ans_n);
158  possible &= ans_f | (ans_m & ans_abc);
159  if (!possible) continue;
160  }
161 
162  unsigned int ans_g, ans_i;
163  {
164  __m128i g = _mm_loadu_si128((const __m128i*)(p - 3 - w));
165  __m128i ii = _mm_loadu_si128((const __m128i*)(p - 3 + w));
166  CHECK_BARRIER(lo, hi, g, ans_g);
167  CHECK_BARRIER(lo, hi, ii, ans_i);
168  possible &= ans_g | (ans_f & ans_p & ans_k);
169  possible &= ans_i | (ans_c & ans_n & ans_k);
170  if (!possible) continue;
171  }
172 
173  unsigned int ans_j, ans_l;
174  {
175  __m128i jj = _mm_loadu_si128((const __m128i*)(p + 3 - w));
176  __m128i l = _mm_loadu_si128((const __m128i*)(p + 3 + w));
177  CHECK_BARRIER(lo, hi, jj, ans_j);
178  CHECK_BARRIER(lo, hi, l, ans_l);
179  const unsigned int ans_ghi = ans_g & ans_h & ans_i;
180  possible &= ans_j | (ans_d & ans_o & ans_ghi);
181  possible &= ans_l | (ans_m & ans_a & ans_ghi);
182  if (!possible) continue;
183  }
184 
185  possible |= (possible >> 16);
186  // if(possible & 0x0f) //Does this make it faster?
187  {
188  if (possible & (1 << 0)) corners.push_back_fast(x + 0, y);
189  if (possible & (1 << 1)) corners.push_back_fast(x + 1, y);
190  if (possible & (1 << 2)) corners.push_back_fast(x + 2, y);
191  if (possible & (1 << 3)) corners.push_back_fast(x + 3, y);
192  if (possible & (1 << 4)) corners.push_back_fast(x + 4, y);
193  if (possible & (1 << 5)) corners.push_back_fast(x + 5, y);
194  if (possible & (1 << 6)) corners.push_back_fast(x + 6, y);
195  if (possible & (1 << 7)) corners.push_back_fast(x + 7, y);
196  }
197  // if(possible & 0xf0) //Does this mak( , fast)r?
198  {
199  if (possible & (1 << 8)) corners.push_back_fast(x + 8, y);
200  if (possible & (1 << 9)) corners.push_back_fast(x + 9, y);
201  if (possible & (1 << 10)) corners.push_back_fast(x + 10, y);
202  if (possible & (1 << 11)) corners.push_back_fast(x + 11, y);
203  if (possible & (1 << 12)) corners.push_back_fast(x + 12, y);
204  if (possible & (1 << 13)) corners.push_back_fast(x + 13, y);
205  if (possible & (1 << 14)) corners.push_back_fast(x + 14, y);
206  if (possible & (1 << 15)) corners.push_back_fast(x + 15, y);
207  }
208  }
209 
210  for (int x = xend; x < I->width - 3; x++)
211  if (is_corner_10<Less>(
212  (const uint8_t*)I->imageData + I->widthStep * y + x,
213  I->widthStep, barrier) ||
214  is_corner_10<Greater>(
215  (const uint8_t*)I->imageData + I->widthStep * y + x,
216  I->widthStep, barrier))
217  corners.push_back_fast(x, y);
218  }
219 
220  // 3 last rows have no features:
221  if (ptr_feat_index_by_row)
222  {
223  *ptr_feat_index_by_row++ = corners.size();
224  *ptr_feat_index_by_row++ = corners.size();
225  *ptr_feat_index_by_row++ = corners.size();
226  }
227 }
228 
229 #endif // MRPT_HAS_SSE2 && MRPT_HAS_OPENCV
230 
231 #if MRPT_HAS_OPENCV
232 
234  const IplImage* I, mrpt::vision::TSimpleFeatureList& corners, int barrier,
235  uint8_t octave, std::vector<size_t>* out_feats_index_by_row)
236 {
237  if (I->width < 22)
238  {
240  I, corners, barrier, octave, out_feats_index_by_row);
241  return;
242  }
243  else if (I->width < 22 || I->height < 7)
244  return;
245 
246 #if MRPT_HAS_SSE2
247  if (mrpt::system::is_aligned<16>(I->imageData) &&
248  mrpt::system::is_aligned<16>(I->imageData + I->widthStep))
249  faster_corner_detect_10<true>(
250  I, corners, barrier, octave, out_feats_index_by_row);
251  else
252  faster_corner_detect_10<false>(
253  I, corners, barrier, octave, out_feats_index_by_row);
254 #else
256  I, corners, barrier, octave, out_feats_index_by_row);
257 #endif
258 }
259 #endif
bool is_aligned< 16 >(const void *ptr)
Definition: memory.h:126
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
STL namespace.
#define CHECK_BARRIER(lo, hi, other, flags)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
unsigned char uint8_t
Definition: rptypes.h:41
void fast_corner_detect_plain_10(const IplImage *i, TSimpleFeatureList &corners, int b, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
const GLubyte * c
Definition: glext.h:6313
void faster_corner_detect_10(const IplImage *I, mrpt::vision::TSimpleFeatureList &corners, int barrier, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
GLsizei stride
Definition: glext.h:3825
GLubyte g
Definition: glext.h:6279
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLenum GLint GLint y
Definition: glext.h:3538
GLenum GLint x
Definition: glext.h:3538
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
GLfloat GLfloat p
Definition: glext.h:6305
void fast_corner_detect_10(const IplImage *I, mrpt::vision::TSimpleFeatureList &corners, int barrier, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019