| 390 | // there is more than one dominant orientation at a given feature location. |
| 391 | template<typename T> |
| 392 | void calcOrientation(float* x_out, float* y_out, unsigned* layer_out, |
| 393 | float* response_out, float* size_out, float* ori_out, |
| 394 | unsigned* counter, const float* x_in, const float* y_in, |
| 395 | const unsigned* layer_in, const float* response_in, |
| 396 | const float* size_in, const unsigned total_feat, |
| 397 | const std::vector<Array<T>>& gauss_pyr, |
| 398 | const unsigned max_feat, const unsigned octave, |
| 399 | const unsigned n_layers, const bool double_input) { |
| 400 | const int n = OriHistBins; |
| 401 | |
| 402 | float hist[OriHistBins]; |
| 403 | float temphist[OriHistBins]; |
| 404 | |
| 405 | for (unsigned f = 0; f < total_feat; f++) { |
| 406 | // Load keypoint information |
| 407 | const float real_x = x_in[f]; |
| 408 | const float real_y = y_in[f]; |
| 409 | const unsigned layer = layer_in[f]; |
| 410 | const float response = response_in[f]; |
| 411 | const float size = size_in[f]; |
| 412 | |
| 413 | const int pt_x = (int)round(real_x / (1 << octave)); |
| 414 | const int pt_y = (int)round(real_y / (1 << octave)); |
| 415 | |
| 416 | // Calculate auxiliary parameters |
| 417 | const float scl_octv = size * 0.5f / (1 << octave); |
| 418 | const int radius = (int)round(OriRadius * scl_octv); |
| 419 | const float sigma = OriSigFctr * scl_octv; |
| 420 | const int len = (radius * 2 + 1); |
| 421 | const float exp_denom = 2.f * sigma * sigma; |
| 422 | |
| 423 | // Points img to correct Gaussian pyramid layer |
| 424 | const Array<T> img = gauss_pyr[octave * (n_layers + 3) + layer]; |
| 425 | const T* img_ptr = img.get(); |
| 426 | |
| 427 | for (int i = 0; i < OriHistBins; i++) hist[i] = 0.f; |
| 428 | |
| 429 | af::dim4 idims = img.dims(); |
| 430 | |
| 431 | // Calculate orientation histogram |
| 432 | for (int l = 0; l < len * len; l++) { |
| 433 | int i = l / len - radius; |
| 434 | int j = l % len - radius; |
| 435 | |
| 436 | int y = pt_y + i; |
| 437 | int x = pt_x + j; |
| 438 | if (y < 1 || y >= idims[0] - 1 || x < 1 || x >= idims[1] - 1) |
| 439 | continue; |
| 440 | |
| 441 | float dx = (float)(IPTR(x + 1, y) - IPTR(x - 1, y)); |
| 442 | float dy = (float)(IPTR(x, y - 1) - IPTR(x, y + 1)); |
| 443 | |
| 444 | float mag = sqrt(dx * dx + dy * dy); |
| 445 | float ori = atan2(dy, dx); |
| 446 | float w = exp(-(i * i + j * j) / exp_denom); |
| 447 | |
| 448 | int bin = round(n * (ori + PI_VAL) / (2.f * PI_VAL)); |
| 449 | bin = bin < n ? bin : 0; |