| 234 | |
| 235 | template<typename T> |
| 236 | void extract_orb(unsigned* desc_out, const unsigned n_feat, float* x_in_out, |
| 237 | float* y_in_out, const float* ori_in, float* size_out, |
| 238 | CParam<T> image, const float scl, const unsigned patch_size) { |
| 239 | const af::dim4 idims = image.dims(); |
| 240 | for (unsigned f = 0; f < n_feat; f++) { |
| 241 | unsigned x = (unsigned)round(x_in_out[f]); |
| 242 | unsigned y = (unsigned)round(y_in_out[f]); |
| 243 | float ori = ori_in[f]; |
| 244 | unsigned size = patch_size; |
| 245 | |
| 246 | unsigned r = ceil(patch_size * sqrt(2.f) / 2.f); |
| 247 | if (x < r || y < r || x >= idims[1] - r || y >= idims[0] - r) continue; |
| 248 | |
| 249 | // Descriptor fixed at 256 bits for now |
| 250 | // Storing descriptor as a vector of 8 x 32-bit unsigned numbers |
| 251 | for (unsigned i = 0; i < 8; i++) { |
| 252 | unsigned v = 0; |
| 253 | |
| 254 | // j < 32 for 256 bits descriptor |
| 255 | for (unsigned j = 0; j < 32; j++) { |
| 256 | // Get position from distribution pattern and values of points |
| 257 | // p1 and p2 |
| 258 | int dist_x = ref_pat[i * 32 * 4 + j * 4]; |
| 259 | int dist_y = ref_pat[i * 32 * 4 + j * 4 + 1]; |
| 260 | T p1 = get_pixel(x, y, ori, size, dist_x, dist_y, image, |
| 261 | patch_size); |
| 262 | |
| 263 | dist_x = ref_pat[i * 32 * 4 + j * 4 + 2]; |
| 264 | dist_y = ref_pat[i * 32 * 4 + j * 4 + 3]; |
| 265 | T p2 = get_pixel(x, y, ori, size, dist_x, dist_y, image, |
| 266 | patch_size); |
| 267 | |
| 268 | // Calculate bit based on p1 and p2 and shifts it to correct |
| 269 | // position |
| 270 | v |= (p1 < p2) << j; |
| 271 | } |
| 272 | |
| 273 | // Store 32 bits of descriptor |
| 274 | desc_out[f * 8 + i] += v; |
| 275 | } |
| 276 | |
| 277 | x_in_out[f] = round(x * scl); |
| 278 | y_in_out[f] = round(y * scl); |
| 279 | size_out[f] = patch_size * scl; |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | } // namespace kernel |
| 284 | } // namespace cpu |