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