| 115 | } |
| 116 | |
| 117 | void CPPNonMaximumSuppressionKernel::run(const Window &window, const ThreadInfo &info) |
| 118 | { |
| 119 | ARM_COMPUTE_UNUSED(info); |
| 120 | ARM_COMPUTE_UNUSED(window); |
| 121 | ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); |
| 122 | ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICPPKernel::window(), window); |
| 123 | |
| 124 | // Auxiliary tensors |
| 125 | std::vector<int> indices_above_thd; |
| 126 | std::vector<float> scores_above_thd; |
| 127 | for (unsigned int i = 0; i < _num_boxes; ++i) |
| 128 | { |
| 129 | const float score_i = *(reinterpret_cast<float *>(_input_scores->ptr_to_element(Coordinates(i)))); |
| 130 | if (score_i >= _score_threshold) |
| 131 | { |
| 132 | scores_above_thd.emplace_back(score_i); |
| 133 | indices_above_thd.emplace_back(i); |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | // Sort selected indices based on scores |
| 138 | const unsigned int num_above_thd = indices_above_thd.size(); |
| 139 | std::vector<unsigned int> sorted_indices; |
| 140 | sorted_indices.resize(num_above_thd); |
| 141 | std::iota(sorted_indices.data(), sorted_indices.data() + num_above_thd, 0); |
| 142 | std::sort(std::begin(sorted_indices), std::end(sorted_indices), |
| 143 | [&](unsigned int first, unsigned int second) |
| 144 | { return scores_above_thd[first] > scores_above_thd[second]; }); |
| 145 | |
| 146 | // Number of output is the minimum between max_detection and the scores above the threshold |
| 147 | const unsigned int num_output = std::min(_max_output_size, num_above_thd); |
| 148 | unsigned int output_idx = 0; |
| 149 | std::vector<bool> visited(num_above_thd, false); |
| 150 | |
| 151 | // Keep only boxes with small IoU |
| 152 | for (unsigned int i = 0; i < num_above_thd; ++i) |
| 153 | { |
| 154 | // Check if the output is full |
| 155 | if (output_idx >= num_output) |
| 156 | { |
| 157 | break; |
| 158 | } |
| 159 | |
| 160 | // Check if it was already visited, if not add it to the output and update the indices counter |
| 161 | if (!visited[sorted_indices[i]]) |
| 162 | { |
| 163 | *(reinterpret_cast<int *>(_output_indices->ptr_to_element(Coordinates(output_idx)))) = |
| 164 | indices_above_thd[sorted_indices[i]]; |
| 165 | visited[sorted_indices[i]] = true; |
| 166 | ++output_idx; |
| 167 | } |
| 168 | else |
| 169 | { |
| 170 | continue; |
| 171 | } |
| 172 | |
| 173 | // Once added one element at the output check if the next ones overlap and can be skipped |
| 174 | for (unsigned int j = i + 1; j < num_above_thd; ++j) |
nothing calls this directly
no test coverage detected