| 513 | // of Lowe's paper. |
| 514 | template<typename T> |
| 515 | void computeDescriptor(float* desc_out, const unsigned desc_len, |
| 516 | const float* x_in, const float* y_in, |
| 517 | const unsigned* layer_in, const float* response_in, |
| 518 | const float* size_in, const float* ori_in, |
| 519 | const unsigned total_feat, |
| 520 | const std::vector<Array<T>>& gauss_pyr, const int d, |
| 521 | const int n, const float scale, const unsigned octave, |
| 522 | const unsigned n_layers) { |
| 523 | UNUSED(response_in); |
| 524 | float desc[128]; |
| 525 | |
| 526 | for (unsigned f = 0; f < total_feat; f++) { |
| 527 | const unsigned layer = layer_in[f]; |
| 528 | float ori = (360.f - ori_in[f]) * PI_VAL / 180.f; |
| 529 | ori = (ori > PI_VAL) ? ori - PI_VAL * 2 : ori; |
| 530 | const float size = size_in[f]; |
| 531 | const int fx = round(x_in[f] * scale); |
| 532 | const int fy = round(y_in[f] * scale); |
| 533 | |
| 534 | // Points img to correct Gaussian pyramid layer |
| 535 | Array<T> img = gauss_pyr[octave * (n_layers + 3) + layer]; |
| 536 | const T* img_ptr = img.get(); |
| 537 | af::dim4 idims = img.dims(); |
| 538 | |
| 539 | float cos_t = cos(ori); |
| 540 | float sin_t = sin(ori); |
| 541 | float bins_per_rad = n / (PI_VAL * 2.f); |
| 542 | float exp_denom = d * d * 0.5f; |
| 543 | float hist_width = DescrSclFctr * size * scale * 0.5f; |
| 544 | int radius = hist_width * sqrt(2.f) * (d + 1.f) * 0.5f + 0.5f; |
| 545 | |
| 546 | int len = radius * 2 + 1; |
| 547 | |
| 548 | for (int i = 0; i < (int)desc_len; i++) desc[i] = 0.f; |
| 549 | |
| 550 | // Calculate orientation histogram |
| 551 | for (int l = 0; l < len * len; l++) { |
| 552 | int i = l / len - radius; |
| 553 | int j = l % len - radius; |
| 554 | |
| 555 | int y = fy + i; |
| 556 | int x = fx + j; |
| 557 | |
| 558 | float x_rot = (j * cos_t - i * sin_t) / hist_width; |
| 559 | float y_rot = (j * sin_t + i * cos_t) / hist_width; |
| 560 | float xbin = x_rot + d / 2 - 0.5f; |
| 561 | float ybin = y_rot + d / 2 - 0.5f; |
| 562 | |
| 563 | if (ybin > -1.0f && ybin < d && xbin > -1.0f && xbin < d && y > 0 && |
| 564 | y < idims[0] - 1 && x > 0 && x < idims[1] - 1) { |
| 565 | float dx = (float)(IPTR(x + 1, y) - IPTR(x - 1, y)); |
| 566 | float dy = (float)(IPTR(x, y - 1) - IPTR(x, y + 1)); |
| 567 | |
| 568 | float grad_mag = sqrt(dx * dx + dy * dy); |
| 569 | float grad_ori = atan2(dy, dx) - ori; |
| 570 | while (grad_ori < 0.0f) grad_ori += PI_VAL * 2; |
| 571 | while (grad_ori >= PI_VAL * 2) grad_ori -= PI_VAL * 2; |
| 572 | |