| 28 | |
| 29 | template<typename T> |
| 30 | unsigned fast(Array<float> &x_out, Array<float> &y_out, Array<float> &score_out, |
| 31 | const Array<T> &in, const float thr, const unsigned arc_length, |
| 32 | const bool nonmax, const float feature_ratio, |
| 33 | const unsigned edge) { |
| 34 | in.eval(); |
| 35 | |
| 36 | dim4 in_dims = in.dims(); |
| 37 | const unsigned max_feat = ceil(in.elements() * feature_ratio); |
| 38 | |
| 39 | // Matrix containing scores for detected features, scores are stored in the |
| 40 | // same coordinates as features, dimensions should be equal to in. |
| 41 | Array<float> V = createEmptyArray<float>(dim4()); |
| 42 | if (nonmax == 1) { |
| 43 | dim4 V_dims(in_dims[0], in_dims[1]); |
| 44 | V = createValueArray<float>(V_dims, 0.f); |
| 45 | V.eval(); |
| 46 | } |
| 47 | getQueue().sync(); |
| 48 | |
| 49 | // Arrays containing all features detected before non-maximal suppression. |
| 50 | dim4 max_feat_dims(max_feat); |
| 51 | Array<float> x = createEmptyArray<float>(max_feat_dims); |
| 52 | Array<float> y = createEmptyArray<float>(max_feat_dims); |
| 53 | Array<float> score = createEmptyArray<float>(max_feat_dims); |
| 54 | |
| 55 | // Feature counter |
| 56 | unsigned count = 0; |
| 57 | |
| 58 | kernel::locate_features<T>(in, V, x, y, score, &count, thr, arc_length, |
| 59 | nonmax, max_feat, edge); |
| 60 | |
| 61 | // If more features than max_feat were detected, feat wasn't populated |
| 62 | // with them anyway, so the real number of features will be that of |
| 63 | // max_feat and not count. |
| 64 | unsigned feat_found = std::min(max_feat, count); |
| 65 | dim4 feat_found_dims(feat_found); |
| 66 | |
| 67 | Array<float> x_total = createEmptyArray<float>(af::dim4()); |
| 68 | Array<float> y_total = createEmptyArray<float>(af::dim4()); |
| 69 | Array<float> score_total = createEmptyArray<float>(af::dim4()); |
| 70 | |
| 71 | if (nonmax == 1) { |
| 72 | x_total = createEmptyArray<float>(feat_found_dims); |
| 73 | y_total = createEmptyArray<float>(feat_found_dims); |
| 74 | score_total = createEmptyArray<float>(feat_found_dims); |
| 75 | |
| 76 | count = 0; |
| 77 | kernel::non_maximal(V, x, y, x_total, y_total, score_total, &count, |
| 78 | feat_found, edge); |
| 79 | |
| 80 | feat_found = std::min(max_feat, count); |
| 81 | } else { |
| 82 | x_total = x; |
| 83 | y_total = y; |
| 84 | score_total = score; |
| 85 | } |
| 86 | |
| 87 | if (feat_found > 0) { |