| 622 | // III-B of Mikolajczyk and Schmid paper. |
| 623 | template<typename T> |
| 624 | void computeGLOHDescriptor(float* desc_out, const unsigned desc_len, |
| 625 | const float* x_in, const float* y_in, |
| 626 | const unsigned* layer_in, const float* response_in, |
| 627 | const float* size_in, const float* ori_in, |
| 628 | const unsigned total_feat, |
| 629 | const std::vector<Array<T>>& gauss_pyr, const int d, |
| 630 | const unsigned rb, const unsigned ab, |
| 631 | const unsigned hb, const float scale, |
| 632 | const unsigned octave, const unsigned n_layers) { |
| 633 | UNUSED(response_in); |
| 634 | float desc[272]; |
| 635 | |
| 636 | for (unsigned f = 0; f < total_feat; f++) { |
| 637 | const unsigned layer = layer_in[f]; |
| 638 | float ori = (360.f - ori_in[f]) * PI_VAL / 180.f; |
| 639 | ori = (ori > PI_VAL) ? ori - PI_VAL * 2 : ori; |
| 640 | const float size = size_in[f]; |
| 641 | const int fx = round(x_in[f] * scale); |
| 642 | const int fy = round(y_in[f] * scale); |
| 643 | |
| 644 | // Points img to correct Gaussian pyramid layer |
| 645 | Array<T> img = gauss_pyr[octave * (n_layers + 3) + layer]; |
| 646 | const T* img_ptr = img.get(); |
| 647 | af::dim4 idims = img.dims(); |
| 648 | |
| 649 | float cos_t = cos(ori); |
| 650 | float sin_t = sin(ori); |
| 651 | float hist_bins_per_rad = hb / (PI_VAL * 2.f); |
| 652 | float polar_bins_per_rad = ab / (PI_VAL * 2.f); |
| 653 | float exp_denom = GLOHRadii[rb - 1] * 0.5f; |
| 654 | |
| 655 | float hist_width = DescrSclFctr * size * scale * 0.5f; |
| 656 | |
| 657 | // Keep same descriptor radius used for SIFT |
| 658 | int radius = hist_width * sqrt(2.f) * (d + 1.f) * 0.5f + 0.5f; |
| 659 | |
| 660 | // Alternative radius size calculation, changing the radius weight |
| 661 | // (rw) in the range of 0.25f-0.75f gives different results, |
| 662 | // increasing it tends to show a better recall rate but with a |
| 663 | // smaller amount of correct matches |
| 664 | // float rw = 0.5f; |
| 665 | // int radius = hist_width * GLOHRadii[rb-1] * rw + 0.5f; |
| 666 | |
| 667 | int len = radius * 2 + 1; |
| 668 | |
| 669 | for (int i = 0; i < (int)desc_len; i++) desc[i] = 0.f; |
| 670 | |
| 671 | // Calculate orientation histogram |
| 672 | for (int l = 0; l < len * len; l++) { |
| 673 | int i = l / len - radius; |
| 674 | int j = l % len - radius; |
| 675 | |
| 676 | int y = fy + i; |
| 677 | int x = fx + j; |
| 678 | |
| 679 | float x_rot = (j * cos_t - i * sin_t); |
| 680 | float y_rot = (j * sin_t + i * cos_t); |
| 681 | |