28 #if MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 30 template <
bool Aligned>
33 uint8_t octave, std::vector<size_t>* out_feats_index_by_row)
38 size_t* ptr_feat_index_by_row;
39 if (out_feats_index_by_row)
41 out_feats_index_by_row->resize(I->height);
42 ptr_feat_index_by_row = &(*out_feats_index_by_row)[0];
46 ptr_feat_index_by_row =
nullptr;
49 const int w = I->width;
50 const int stride = 3 * I->widthStep;
53 const __m128i barriers = _mm_set1_epi8((
uint8_t)barrier);
55 int xend = I->width - 3;
56 xend -= (I->width - 3) % 16;
59 if (ptr_feat_index_by_row)
61 *ptr_feat_index_by_row++ = corners.
size();
62 *ptr_feat_index_by_row++ = corners.
size();
63 *ptr_feat_index_by_row++ = corners.
size();
66 for (
int y = 3;
y < I->height - 3;
y++)
68 if (ptr_feat_index_by_row)
69 *ptr_feat_index_by_row++ = corners.
size();
71 for (
int x = 3;
x < 16;
x++)
72 if (is_corner_9<Less>(
73 (
const uint8_t*)I->imageData + I->widthStep *
y +
x,
74 I->widthStep, barrier) ||
76 (
const uint8_t*)I->imageData + I->widthStep *
y +
x,
77 I->widthStep, barrier))
80 for (
int x = 16;
x < xend;
x += 16)
83 (
const uint8_t*)I->imageData + I->widthStep *
y +
87 const __m128i here = load_si128<Aligned>((
const __m128i*)(
p));
88 lo = _mm_subs_epu8(here, barriers);
89 hi = _mm_adds_epu8(barriers, here);
91 unsigned int ans_0, ans_8, possible;
93 __m128i top = load_si128<Aligned>((
const __m128i*)(
p -
stride));
95 load_si128<Aligned>((
const __m128i*)(
p +
stride));
99 possible = ans_0 | ans_8;
100 if (!possible)
continue;
103 unsigned int ans_15, ans_1;
105 __m128i
a = _mm_loadu_si128((
const __m128i*)(
p - 1 -
stride));
106 __m128i
c = _mm_insert_epi16(
107 _mm_srli_si128(
a, 2),
108 *(
const unsigned short*)(
p + 15 -
stride), 7);
111 possible &= ans_8 | (ans_15 & ans_1);
112 if (!possible)
continue;
115 unsigned int ans_9, ans_7;
117 __m128i d = _mm_loadu_si128((
const __m128i*)(
p - 1 +
stride));
118 __m128i f = _mm_insert_epi16(
119 _mm_srli_si128(d, 2),
120 *(
const unsigned short*)(
p + 15 +
stride), 7);
123 possible &= ans_9 | (ans_0 & ans_1);
124 possible &= ans_7 | (ans_15 & ans_0);
125 if (!possible)
continue;
128 unsigned int ans_12, ans_4;
130 __m128i left = _mm_loadu_si128((
const __m128i*)(
p - 3));
131 __m128i right = _mm_loadu_si128((
const __m128i*)(
p + 3));
134 possible &= ans_12 | (ans_4 & (ans_1 | ans_7));
135 possible &= ans_4 | (ans_12 & (ans_9 | ans_15));
136 if (!possible)
continue;
139 unsigned int ans_14, ans_6;
141 __m128i ul = _mm_loadu_si128((
const __m128i*)(
p - 2 - 2 *
w));
142 __m128i lr = _mm_loadu_si128((
const __m128i*)(
p + 2 + 2 *
w));
146 const unsigned int ans_6_7 = ans_6 & ans_7;
147 possible &= ans_14 | (ans_6_7 & (ans_4 | (ans_8 & ans_9)));
148 possible &= ans_1 | (ans_6_7) | ans_12;
151 const unsigned int ans_14_15 = ans_14 & ans_15;
153 ans_6 | (ans_14_15 & (ans_12 | (ans_0 & ans_1)));
154 possible &= ans_9 | (ans_14_15) | ans_4;
156 if (!possible)
continue;
159 unsigned int ans_10, ans_2;
161 __m128i ll = _mm_loadu_si128((
const __m128i*)(
p - 2 + 2 *
w));
162 __m128i ur = _mm_loadu_si128((
const __m128i*)(
p + 2 - 2 *
w));
166 const unsigned int ans_1_2 = ans_1 & ans_2;
167 possible &= ans_10 | (ans_1_2 & ((ans_0 & ans_15) | ans_4));
168 possible &= ans_12 | (ans_1_2) | (ans_6 & ans_7);
171 const unsigned int ans_9_10 = ans_9 & ans_10;
172 possible &= ans_2 | (ans_9_10 & ((ans_7 & ans_8) | ans_12));
173 possible &= ans_4 | (ans_9_10) | (ans_14 & ans_15);
175 possible &= ans_8 | ans_14 | ans_2;
176 possible &= ans_0 | ans_10 | ans_6;
177 if (!possible)
continue;
180 unsigned int ans_13, ans_5;
182 __m128i
g = _mm_loadu_si128((
const __m128i*)(
p - 3 -
w));
183 __m128i l = _mm_loadu_si128((
const __m128i*)(
p + 3 +
w));
186 const unsigned int ans_15_0 = ans_15 & ans_0;
187 const unsigned int ans_7_8 = ans_7 & ans_8;
189 const unsigned int ans_12_13 = ans_12 & ans_13;
191 ans_5 | (ans_12_13 & ans_14 & ((ans_15_0) | ans_10));
192 possible &= ans_7 | (ans_1 & ans_2) | (ans_12_13);
193 possible &= ans_2 | (ans_12_13) | (ans_7_8);
196 const unsigned int ans_4_5 = ans_4 & ans_5;
197 const unsigned int ans_9_10 = ans_9 & ans_10;
199 ans_13 | (ans_4_5 & ans_6 & ((ans_7_8) | ans_2));
200 possible &= ans_15 | (ans_4_5) | (ans_9_10);
201 possible &= ans_10 | (ans_4_5) | (ans_15_0);
202 possible &= ans_15 | (ans_9_10) | (ans_4_5);
205 possible &= ans_8 | (ans_13 & ans_14) | ans_2;
206 possible &= ans_0 | (ans_5 & ans_6) | ans_10;
207 if (!possible)
continue;
210 unsigned int ans_11, ans_3;
212 __m128i ii = _mm_loadu_si128((
const __m128i*)(
p - 3 +
w));
213 __m128i jj = _mm_loadu_si128((
const __m128i*)(
p + 3 -
w));
217 const unsigned int ans_2_3 = ans_2 & ans_3;
218 possible &= ans_11 | (ans_2_3 & ans_4 &
219 ((ans_0 & ans_1) | (ans_5 & ans_6)));
220 possible &= ans_13 | (ans_7 & ans_8) | (ans_2_3);
221 possible &= ans_8 | (ans_2_3) | (ans_13 & ans_14);
224 const unsigned int ans_11_12 = ans_11 & ans_12;
225 possible &= ans_3 | (ans_10 & ans_11_12 &
226 ((ans_8 & ans_9) | (ans_13 & ans_14)));
227 possible &= ans_1 | (ans_11_12) | (ans_6 & ans_7);
228 possible &= ans_6 | (ans_0 & ans_1) | (ans_11_12);
231 const unsigned int ans_3_4 = ans_3 & ans_4;
232 possible &= ans_9 | (ans_3_4) | (ans_14 & ans_15);
233 possible &= ans_14 | (ans_8 & ans_9) | (ans_3_4);
236 const unsigned int ans_10_11 = ans_10 & ans_11;
237 possible &= ans_5 | (ans_15 & ans_0) | (ans_10_11);
238 possible &= ans_0 | (ans_10_11) | (ans_5 & ans_6);
240 if (!possible)
continue;
243 possible |= (possible >> 16);
247 if (possible & (1 << 0))
249 if (possible & (1 << 1))
251 if (possible & (1 << 2))
253 if (possible & (1 << 3))
255 if (possible & (1 << 4))
257 if (possible & (1 << 5))
259 if (possible & (1 << 6))
261 if (possible & (1 << 7))
266 if (possible & (1 << 8))
268 if (possible & (1 << 9))
270 if (possible & (1 << 10))
272 if (possible & (1 << 11))
274 if (possible & (1 << 12))
276 if (possible & (1 << 13))
278 if (possible & (1 << 14))
280 if (possible & (1 << 15))
285 for (
int x = xend;
x < I->width - 3;
x++)
286 if (is_corner_9<Less>(
287 (
const uint8_t*)I->imageData + I->widthStep *
y +
x,
288 I->widthStep, barrier) ||
289 is_corner_9<Greater>(
290 (
const uint8_t*)I->imageData + I->widthStep *
y +
x,
291 I->widthStep, barrier))
296 if (ptr_feat_index_by_row)
298 *ptr_feat_index_by_row++ = corners.size();
299 *ptr_feat_index_by_row++ = corners.size();
300 *ptr_feat_index_by_row++ = corners.size();
304 #endif // MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 310 uint8_t octave, std::vector<size_t>* out_feats_index_by_row)
315 I, corners, barrier, octave, out_feats_index_by_row);
318 else if (I->width < 22 || I->height < 7)
324 faster_corner_detect_9<true>(
325 I, corners, barrier, octave, out_feats_index_by_row);
327 faster_corner_detect_9<false>(
328 I, corners, barrier, octave, out_feats_index_by_row);
331 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 push_back_fast(const FEATURE &f)
void fast_corner_detect_9(const IplImage *I, mrpt::vision::TSimpleFeatureList &corners, int barrier, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
#define CHECK_BARRIER(lo, hi, other, flags)
GLubyte GLubyte GLubyte GLubyte w
void fast_corner_detect_plain_9(const IplImage *i, TSimpleFeatureList &corners, int b, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
void faster_corner_detect_9(const IplImage *I, mrpt::vision::TSimpleFeatureList &corners, int barrier, uint8_t octave, std::vector< size_t > *out_feats_index_by_row)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLubyte GLubyte GLubyte a