27 template <
int I,
int N>
32 unsigned int three,
const uint8_t*
p,
const int w,
const int barrier,
35 const int BIT = 1 << I;
38 if (three & (BIT << 16))
40 if (is_corner_12<Greater>(
p,
w, barrier)) corners.push_back(
p);
44 if (is_corner_12<Less>(
p,
w, barrier)) corners.push_back(
p);
56 unsigned int,
const uint8_t*,
const int,
const int, C&)
61 template <
int CHUNKS,
class C>
63 unsigned int three,
const uint8_t*
p,
const int w,
const int barrier,
66 three |= (three >> 16);
67 const int BITS = 16 / CHUNKS;
68 const int mask = ((1 << BITS) - 1);
69 for (
int i = 0; i < CHUNKS; ++i)
78 #if MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 80 template <
bool Aligned>
83 uint8_t octave, std::vector<size_t>* out_feats_index_by_row)
88 size_t *ptr_feat_index_by_row, *ptr_feat_index_end;
89 if (out_feats_index_by_row)
91 out_feats_index_by_row->resize(I->height);
92 ptr_feat_index_by_row = &(*out_feats_index_by_row)[0];
94 ptr_feat_index_by_row + out_feats_index_by_row->size();
98 ptr_feat_index_by_row =
nullptr;
99 ptr_feat_index_end =
nullptr;
102 const int w = I->width;
103 const int stride = 3 * I->widthStep;
104 typedef std::list<const uint8_t*> Passed;
110 const __m128i barriers = _mm_set1_epi8((
uint8_t)barrier);
112 for (
int i = 3; i < I->height - 3; ++i)
115 (
const uint8_t*)I->imageData + I->widthStep * i;
116 for (
int j = 0; j <
w / 16; ++j,
p += 16)
120 const __m128i here = load_si128<Aligned>((
const __m128i*)(
p));
121 lo = _mm_subs_epu8(here, barriers);
122 hi = _mm_adds_epu8(barriers, here);
124 const __m128i above =
125 load_si128<Aligned>((
const __m128i*)(
p -
stride));
126 const __m128i below =
127 load_si128<Aligned>((
const __m128i*)(
p +
stride));
128 unsigned int up_flags, down_flags;
131 const unsigned int either_ud = up_flags | down_flags;
134 unsigned int left_flags;
136 const __m128i other =
137 _mm_loadu_si128((
const __m128i*)(
p - 3));
140 const unsigned int both_ud = up_flags & down_flags;
141 if (both_ud | (either_ud & left_flags))
143 unsigned int right_flags;
145 const __m128i other =
146 _mm_loadu_si128((
const __m128i*)(
p + 3));
149 const unsigned int at_least_three =
150 (either_ud & (left_flags & right_flags)) |
151 (both_ud & (left_flags | right_flags));
154 process_16<4>(at_least_three,
p,
w, barrier, passed);
161 for (
int j = (
w / 16) * 16; j <
w - 3; j++,
p++)
163 int cb = *
p + barrier;
164 int c_b = *
p - barrier;
168 if (!num_above && !num_below)
continue;
171 num_above +=
p[-3] > cb;
172 num_below +=
p[-3] < c_b;
176 if (!(num_above & 1))
177 num_above +=
p[3] > cb;
180 if ((num_above & 1) && is_corner_12<Greater>(
p,
w, barrier))
183 else if (num_below & 2)
185 if (!(num_below & 1)) num_below +=
p[3] < c_b;
187 if ((num_below & 1) && is_corner_12<Less>(
p,
w, barrier))
196 if (ptr_feat_index_by_row)
198 *ptr_feat_index_by_row++ = corners.
size();
199 *ptr_feat_index_by_row++ = corners.
size();
200 *ptr_feat_index_by_row++ = corners.
size();
205 const uint8_t* row_start = (
const uint8_t*)I->imageData + I->widthStep * 3;
211 if (ptr_feat_index_by_row)
212 *ptr_feat_index_by_row++ = corners.
size();
214 row_start = (
const uint8_t*)I->imageData +
215 I->widthStep * (++
row);
218 int x = *it - row_start;
219 if (
x > 2 &&
x <
w - 3)
224 if (ptr_feat_index_by_row)
226 *ptr_feat_index_by_row++ = corners.
size();
227 *ptr_feat_index_by_row++ = corners.
size();
228 *ptr_feat_index_by_row++ = corners.
size();
229 ASSERT_(ptr_feat_index_by_row == ptr_feat_index_end)
233 #endif // MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 239 uint8_t octave, std::vector<size_t>* out_feats_index_by_row)
244 I, corners, barrier, octave, out_feats_index_by_row);
247 else if (I->width < 22 || I->height < 7)
253 faster_corner_detect_12<true>(
254 I, corners, barrier, octave, out_feats_index_by_row);
256 faster_corner_detect_12<false>(
257 I, corners, barrier, octave, out_feats_index_by_row);
260 I, corners, barrier, octave, out_feats_index_by_row);
bool is_aligned< 16 >(const void *ptr)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
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)
void push_back_fast(const FEATURE &f)
static void eval(unsigned int three, const uint8_t *p, const int w, const int barrier, C &corners)
for(ctr=DCTSIZE;ctr > 0;ctr--)
#define CHECK_BARRIER(lo, hi, other, flags)
GLubyte GLubyte GLubyte GLubyte w
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
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)
void process_16(unsigned int three, const uint8_t *p, const int w, const int barrier, C &corners)