27 #if MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 29 template <
bool Aligned>
36 size_t *ptr_feat_index_by_row;
37 if (out_feats_index_by_row)
39 out_feats_index_by_row->resize(I->height);
40 ptr_feat_index_by_row = &(*out_feats_index_by_row)[0];
43 ptr_feat_index_by_row = NULL;
48 if (ptr_feat_index_by_row) {
49 *ptr_feat_index_by_row++ = corners.
size();
50 *ptr_feat_index_by_row++ = corners.
size();
51 *ptr_feat_index_by_row++ = corners.
size();
54 const int w = I->width;
55 const int stride = 3*I->widthStep;
58 const __m128i barriers = _mm_set1_epi8((
uint8_t)barrier);
60 int xend = I->width - 3;
61 xend -= (I->width-3) % 16;
63 for(
int y=3;
y < I->height - 3;
y++)
65 if (ptr_feat_index_by_row)
66 *ptr_feat_index_by_row++=corners.
size();
68 for(
int x=3;
x < 16;
x++)
69 if(is_corner_10<Less>((
const uint8_t*)I->imageData+I->widthStep*
y+
x, I->widthStep, barrier) || is_corner_10<Greater>((
const uint8_t*)I->imageData+I->widthStep*
y+
x, I->widthStep, barrier))
72 for(
int x=16;
x < xend;
x+=16)
77 const __m128i here = load_si128<Aligned>((
const __m128i*)(
p));
78 lo = _mm_subs_epu8(here, barriers);
79 hi = _mm_adds_epu8(barriers, here);
81 unsigned int ans_b, ans_e;
83 __m128i top = load_si128<Aligned>((
const __m128i*)(
p-
stride));
84 __m128i bottom = load_si128<Aligned>((
const __m128i*)(
p+
stride));
92 unsigned int ans_m, ans_p, possible;
94 __m128i ul = _mm_loadu_si128((
const __m128i*)(
p-2-2*
w));
95 __m128i lr = _mm_loadu_si128((
const __m128i*)(
p+2+2*
w));
98 possible = (ans_m & ans_b) | (ans_e & ans_p);
103 unsigned int ans_o, ans_n;
105 __m128i ll = _mm_loadu_si128((
const __m128i*)(
p-2+2*
w));
106 __m128i ur = _mm_loadu_si128((
const __m128i*)(
p+2-2*
w));
109 possible &= ans_o | (ans_b & ans_n);
110 possible &= ans_n | (ans_e & ans_o);
115 unsigned int ans_h, ans_k;
117 __m128i left = _mm_loadu_si128((
const __m128i*)(
p-3));
118 __m128i right = _mm_loadu_si128((
const __m128i*)(
p+3));
121 possible &= ans_h | (ans_n & ans_k & ans_p);
122 possible &= ans_k | (ans_m & ans_h & ans_o);
127 unsigned int ans_a, ans_c;
129 __m128i
a = _mm_loadu_si128((
const __m128i*)(
p-1-
stride));
130 __m128i
c = _mm_insert_epi16(_mm_srli_si128(
a,2), *(
const unsigned short*)(
p+15-
stride), 7);
134 possible &= ans_a | (ans_e & ans_p);
135 possible &= ans_c | (ans_o & ans_e);
140 unsigned int ans_d, ans_f;
142 __m128i d = _mm_loadu_si128((
const __m128i*)(
p-1+
stride));
143 __m128i f = _mm_insert_epi16(_mm_srli_si128(d,2), *(
const unsigned short*)(
p+15+
stride), 7);
147 const unsigned int ans_abc = ans_a & ans_b & ans_c;
148 possible &= ans_d | (ans_abc & ans_n);
149 possible &= ans_f | (ans_m & ans_abc);
154 unsigned int ans_g, ans_i;
156 __m128i
g = _mm_loadu_si128((
const __m128i*)(
p-3-
w));
157 __m128i ii = _mm_loadu_si128((
const __m128i*)(
p-3+
w));
160 possible &= ans_g | (ans_f & ans_p & ans_k);
161 possible &= ans_i | (ans_c & ans_n & ans_k);
166 unsigned int ans_j, ans_l;
168 __m128i jj = _mm_loadu_si128((
const __m128i*)(
p+3-
w));
169 __m128i l = _mm_loadu_si128((
const __m128i*)(
p+3+
w));
172 const unsigned int ans_ghi = ans_g & ans_h & ans_i;
173 possible &= ans_j | (ans_d & ans_o & ans_ghi);
174 possible &= ans_l | (ans_m & ans_a & ans_ghi);
179 possible |= (possible >> 16);
182 if(possible & (1<< 0))
184 if(possible & (1<< 1))
186 if(possible & (1<< 2))
188 if(possible & (1<< 3))
190 if(possible & (1<< 4))
192 if(possible & (1<< 5))
194 if(possible & (1<< 6))
196 if(possible & (1<< 7))
201 if(possible & (1<< 8))
203 if(possible & (1<< 9))
205 if(possible & (1<<10))
207 if(possible & (1<<11))
209 if(possible & (1<<12))
211 if(possible & (1<<13))
213 if(possible & (1<<14))
215 if(possible & (1<<15))
220 for(
int x=xend;
x < I->width - 3;
x++)
221 if(is_corner_10<Less>((
const uint8_t*)I->imageData+I->widthStep*
y+
x, I->widthStep, barrier) || is_corner_10<Greater>((
const uint8_t*)I->imageData+I->widthStep*
y+
x, I->widthStep, barrier))
226 if (ptr_feat_index_by_row) {
227 *ptr_feat_index_by_row++ = corners.size();
228 *ptr_feat_index_by_row++ = corners.size();
229 *ptr_feat_index_by_row++ = corners.size();
234 #endif // MRPT_HAS_SSE2 && MRPT_HAS_OPENCV 246 else if (I->width < 22 || I->height < 7)
251 faster_corner_detect_10<true>(I, corners, barrier, octave,out_feats_index_by_row);
253 faster_corner_detect_10<false>(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)