27 #if MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 29 template <
bool Aligned>
32 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;
50 if (ptr_feat_index_by_row)
52 *ptr_feat_index_by_row++ = corners.
size();
53 *ptr_feat_index_by_row++ = corners.
size();
54 *ptr_feat_index_by_row++ = corners.
size();
57 const int w = I->width;
58 const int stride = 3 * I->widthStep;
61 const __m128i barriers = _mm_set1_epi8((
uint8_t)barrier);
63 int xend = I->width - 3;
64 xend -= (I->width - 3) % 16;
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_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))
80 for (
int x = 16;
x < xend;
x += 16)
83 (
const uint8_t*)I->imageData + I->widthStep *
y +
x;
86 const __m128i here = load_si128<Aligned>((
const __m128i*)(
p));
87 lo = _mm_subs_epu8(here, barriers);
88 hi = _mm_adds_epu8(barriers, here);
90 unsigned int ans_b, ans_e;
92 __m128i top = load_si128<Aligned>((
const __m128i*)(
p -
stride));
94 load_si128<Aligned>((
const __m128i*)(
p +
stride));
98 if (!(ans_b | ans_e))
continue;
101 unsigned int ans_m, ans_p, possible;
103 __m128i ul = _mm_loadu_si128((
const __m128i*)(
p - 2 - 2 *
w));
104 __m128i lr = _mm_loadu_si128((
const __m128i*)(
p + 2 + 2 *
w));
107 possible = (ans_m & ans_b) | (ans_e & ans_p);
108 if (!possible)
continue;
111 unsigned int ans_o, ans_n;
113 __m128i ll = _mm_loadu_si128((
const __m128i*)(
p - 2 + 2 *
w));
114 __m128i ur = _mm_loadu_si128((
const __m128i*)(
p + 2 - 2 *
w));
117 possible &= ans_o | (ans_b & ans_n);
118 possible &= ans_n | (ans_e & ans_o);
119 if (!possible)
continue;
122 unsigned int ans_h, ans_k;
124 __m128i left = _mm_loadu_si128((
const __m128i*)(
p - 3));
125 __m128i right = _mm_loadu_si128((
const __m128i*)(
p + 3));
128 possible &= ans_h | (ans_n & ans_k & ans_p);
129 possible &= ans_k | (ans_m & ans_h & ans_o);
130 if (!possible)
continue;
133 unsigned int ans_a, ans_c;
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);
142 possible &= ans_a | (ans_e & ans_p);
143 possible &= ans_c | (ans_o & ans_e);
144 if (!possible)
continue;
147 unsigned int ans_d, ans_f;
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);
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;
162 unsigned int ans_g, ans_i;
164 __m128i
g = _mm_loadu_si128((
const __m128i*)(
p - 3 -
w));
165 __m128i ii = _mm_loadu_si128((
const __m128i*)(
p - 3 +
w));
168 possible &= ans_g | (ans_f & ans_p & ans_k);
169 possible &= ans_i | (ans_c & ans_n & ans_k);
170 if (!possible)
continue;
173 unsigned int ans_j, ans_l;
175 __m128i jj = _mm_loadu_si128((
const __m128i*)(
p + 3 -
w));
176 __m128i l = _mm_loadu_si128((
const __m128i*)(
p + 3 +
w));
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;
185 possible |= (possible >> 16);
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))
221 if (ptr_feat_index_by_row)
223 *ptr_feat_index_by_row++ = corners.size();
224 *ptr_feat_index_by_row++ = corners.size();
225 *ptr_feat_index_by_row++ = corners.size();
229 #endif // MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 235 uint8_t octave, std::vector<size_t>* out_feats_index_by_row)
240 I, corners, barrier, octave, out_feats_index_by_row);
243 else if (I->width < 22 || I->height < 7)
249 faster_corner_detect_10<true>(
250 I, corners, barrier, octave, out_feats_index_by_row);
252 faster_corner_detect_10<false>(
253 I, corners, barrier, octave, out_feats_index_by_row);
256 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)
#define CHECK_BARRIER(lo, hi, other, flags)
GLubyte GLubyte GLubyte GLubyte w
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.
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)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLubyte GLubyte GLubyte a
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)