| 22 | |
| 23 | template<typename T> |
| 24 | unsigned susan(Array<float> &x_out, Array<float> &y_out, Array<float> &resp_out, |
| 25 | const Array<T> &in, const unsigned radius, const float diff_thr, |
| 26 | const float geom_thr, const float feature_ratio, |
| 27 | const unsigned edge) { |
| 28 | dim4 idims = in.dims(); |
| 29 | |
| 30 | const unsigned corner_lim = in.elements() * feature_ratio; |
| 31 | Array<float> x_corners = createEmptyArray<float>({corner_lim}); |
| 32 | Array<float> y_corners = createEmptyArray<float>({corner_lim}); |
| 33 | Array<float> resp_corners = createEmptyArray<float>({corner_lim}); |
| 34 | |
| 35 | auto resp = memAlloc<float>(in.elements()); |
| 36 | |
| 37 | kernel::susan<T>(resp.get(), in.get(), in.getOffset(), idims[0], idims[1], |
| 38 | diff_thr, geom_thr, edge, radius); |
| 39 | |
| 40 | unsigned corners_found = kernel::nonMaximal<T>( |
| 41 | x_corners.get(), y_corners.get(), resp_corners.get(), idims[0], |
| 42 | idims[1], resp.get(), edge, corner_lim); |
| 43 | |
| 44 | const unsigned corners_out = std::min(corners_found, corner_lim); |
| 45 | if (corners_out == 0) { |
| 46 | x_out = createEmptyArray<float>(dim4()); |
| 47 | y_out = createEmptyArray<float>(dim4()); |
| 48 | resp_out = createEmptyArray<float>(dim4()); |
| 49 | } else { |
| 50 | vector<af_seq> idx{{0., static_cast<double>(corners_out - 1.0), 1.}}; |
| 51 | x_out = createSubArray(x_corners, idx); |
| 52 | y_out = createSubArray(y_corners, idx); |
| 53 | resp_out = createSubArray(resp_corners, idx); |
| 54 | } |
| 55 | return corners_out; |
| 56 | } |
| 57 | |
| 58 | #define INSTANTIATE(T) \ |
| 59 | template unsigned susan<T>( \ |