diff --git a/src/runtime/CPP/functions/CPPDetectionOutputLayer.cpp b/src/runtime/CPP/functions/CPPDetectionOutputLayer.cpp
new file mode 100644
index 0000000..61005ab
--- /dev/null
+++ b/src/runtime/CPP/functions/CPPDetectionOutputLayer.cpp
@@ -0,0 +1,585 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/runtime/CPP/functions/CPPDetectionOutputLayer.h"
+
+#include "arm_compute/core/Error.h"
+#include "arm_compute/core/Helpers.h"
+#include "arm_compute/core/Validate.h"
+#include "support/ToolchainSupport.h"
+
+#include <list>
+
+namespace arm_compute
+{
+namespace
+{
+Status validate_arguments(const ITensorInfo *input_loc, const ITensorInfo *input_conf, const ITensorInfo *input_priorbox, const ITensorInfo *output, DetectionOutputLayerInfo info)
+{
+    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input_loc, input_conf, input_priorbox, output);
+    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input_loc, 1, DataType::F32);
+    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input_loc, input_conf, input_priorbox);
+    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_loc->num_dimensions() > 2, "The location input tensor should be [C1, N].");
+    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_conf->num_dimensions() > 2, "The location input tensor should be [C2, N].");
+    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_priorbox->num_dimensions() > 3, "The priorbox input tensor should be [C3, 2, N].");
+
+    ARM_COMPUTE_RETURN_ERROR_ON_MSG(info.eta() <= 0.f && info.eta() > 1.f, "Eta should be between 0 and 1");
+
+    const int num_priors = input_priorbox->tensor_shape()[0] / 4;
+    ARM_COMPUTE_RETURN_ERROR_ON_MSG(static_cast<size_t>((num_priors * info.num_loc_classes() * 4)) != input_loc->tensor_shape()[0], "Number of priors must match number of location predictions.");
+    ARM_COMPUTE_RETURN_ERROR_ON_MSG(static_cast<size_t>((num_priors * info.num_classes())) != input_conf->tensor_shape()[0], "Number of priors must match number of confidence predictions.");
+
+    // Validate configured output
+    if(output->total_size() != 0)
+    {
+        const unsigned int max_size = info.keep_top_k() * (input_loc->num_dimensions() > 1 ? input_loc->dimension(1) : 1);
+        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(output->tensor_shape(), TensorShape(7U, max_size));
+        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input_loc, output);
+    }
+
+    return Status{};
+}
+
+/** Function used to sort pair<float, T> in descend order based on the score (first) value.
+ */
+template <typename T>
+bool SortScorePairDescend(const std::pair<float, T> &pair1,
+                          const std::pair<float, T> &pair2)
+{
+    return pair1.first > pair2.first;
+}
+
+/** Get location predictions from input_loc.
+ *
+ * @param[in]  input_loc                The input location prediction.
+ * @param[in]  num                      The number of images.
+ * @param[in]  num_priors               number of predictions per class.
+ * @param[in]  num_loc_classes          number of location classes. It is 1 if share_location is true,
+ *                                      and is equal to number of classes needed to predict otherwise.
+ * @param[in]  share_location           If true, all classes share the same location prediction.
+ * @param[out] all_location_predictions All the location predictions.
+ *
+ */
+void retrieve_all_loc_predictions(const ITensor *input_loc, const int num,
+                                  const int num_priors, const int num_loc_classes,
+                                  const bool share_location, std::vector<LabelBBox> &all_location_predictions)
+{
+    for(int i = 0; i < num; ++i)
+    {
+        for(int c = 0; c < num_loc_classes; ++c)
+        {
+            int label = share_location ? -1 : c;
+            if(all_location_predictions[i].find(label) == all_location_predictions[i].end())
+            {
+                all_location_predictions[i][label].resize(num_priors);
+            }
+            else
+            {
+                ARM_COMPUTE_ERROR_ON(all_location_predictions[i][label].size() != static_cast<size_t>(num_priors));
+                break;
+            }
+        }
+    }
+    for(int i = 0; i < num; ++i)
+    {
+        for(int p = 0; p < num_priors; ++p)
+        {
+            for(int c = 0; c < num_loc_classes; ++c)
+            {
+                const int label    = share_location ? -1 : c;
+                const int base_ptr = i * num_priors * num_loc_classes * 4 + p * num_loc_classes * 4 + c * 4;
+                //xmin, ymin, xmax, ymax
+                all_location_predictions[i][label][p][0] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr)));
+                all_location_predictions[i][label][p][1] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr + 1)));
+                all_location_predictions[i][label][p][2] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr + 2)));
+                all_location_predictions[i][label][p][3] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr + 3)));
+            }
+        }
+    }
+}
+
+/** Get confidence predictions from input_conf.
+ *
+ * @param[in]  input_loc                The input location prediction.
+ * @param[in]  num                      The number of images.
+ * @param[in]  num_priors               Number of predictions per class.
+ * @param[in]  num_loc_classes          Number of location classes. It is 1 if share_location is true,
+ *                                      and is equal to number of classes needed to predict otherwise.
+ * @param[out] all_location_predictions All the location predictions.
+ *
+ */
+void retrieve_all_conf_scores(const ITensor *input_conf, const int num,
+                              const int num_priors, const int                 num_classes,
+                              std::vector<std::map<int, std::vector<float>>> &all_confidence_scores)
+{
+    std::vector<float> tmp_buffer;
+    tmp_buffer.resize(num * num_priors * num_classes);
+    for(int i = 0; i < num; ++i)
+    {
+        for(int c = 0; c < num_classes; ++c)
+        {
+            for(int p = 0; p < num_priors; ++p)
+            {
+                tmp_buffer[i * num_classes * num_priors + c * num_priors + p] =
+                    *reinterpret_cast<float *>(input_conf->ptr_to_element(Coordinates(i * num_classes * num_priors + p * num_classes + c)));
+            }
+        }
+    }
+    for(int i = 0; i < num; ++i)
+    {
+        for(int c = 0; c < num_classes; ++c)
+        {
+            all_confidence_scores[i][c].resize(num_priors);
+            all_confidence_scores[i][c].assign(&tmp_buffer[i * num_classes * num_priors + c * num_priors],
+                                               &tmp_buffer[i * num_classes * num_priors + c * num_priors + num_priors]);
+        }
+    }
+}
+
+/** Get prior boxes from input_priorbox.
+ *
+ * @param[in]  input_priorbox           The input location prediction.
+ * @param[in]  num_priors               Number of priors.
+ * @param[in]  num_loc_classes          number of location classes. It is 1 if share_location is true,
+ *                                      and is equal to number of classes needed to predict otherwise.
+ * @param[out] all_prior_bboxes         If true, all classes share the same location prediction.
+ * @param[out] all_location_predictions All the location predictions.
+ *
+ */
+void retrieve_all_priorbox(const ITensor               *input_priorbox,
+                           const int                    num_priors,
+                           std::vector<NormalizedBBox> &all_prior_bboxes,
+                           std::vector<std::array<float, 4>> &all_prior_variances)
+{
+    for(int i = 0; i < num_priors; ++i)
+    {
+        all_prior_bboxes[i] = { *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4))),
+                                *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4 + 1))),
+                                *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4 + 2))),
+                                *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4 + 3)))
+                              };
+    }
+
+    std::array<float, 4> var({ 0, 0, 0, 0 });
+    for(int i = 0; i < num_priors; ++i)
+    {
+        for(int j = 0; j < 4; ++j)
+        {
+            var[j] = *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates((num_priors + i) * 4 + j)));
+        }
+        all_prior_variances[i] = var;
+    }
+}
+
+/** Decode a bbox according to a prior bbox.
+ *
+ * @param[in]  prior_bbox                 The input prior bounding boxes.
+ * @param[in]  prior_variance             The corresponding input variance.
+ * @param[in]  code_type                  The detection output code type used to decode the results.
+ * @param[in]  variance_encoded_in_target If true, the variance is encoded in target.
+ * @param[in]  clip_bbox                  If true, the results should be between 0.f and 1.f.
+ * @param[in]  bbox                       The input bbox to decode
+ * @param[out] decode_bbox                The decoded bboxes.
+ *
+ */
+void DecodeBBox(const NormalizedBBox &prior_bbox, const std::array<float, 4> &prior_variance,
+                const DetectionOutputLayerCodeType code_type, const bool variance_encoded_in_target,
+                const bool clip_bbox, const NormalizedBBox &bbox, NormalizedBBox &decode_bbox)
+{
+    // if the variance is encoded in target, we simply need to add the offset predictions
+    // otherwise we need to scale the offset accordingly.
+    switch(code_type)
+    {
+        case DetectionOutputLayerCodeType::CORNER:
+        {
+            decode_bbox[0] = prior_bbox[0] + (variance_encoded_in_target ? bbox[0] : prior_variance[0] * bbox[0]);
+            decode_bbox[1] = prior_bbox[1] + (variance_encoded_in_target ? bbox[1] : prior_variance[1] * bbox[1]);
+            decode_bbox[2] = prior_bbox[2] + (variance_encoded_in_target ? bbox[2] : prior_variance[2] * bbox[2]);
+            decode_bbox[3] = prior_bbox[3] + (variance_encoded_in_target ? bbox[3] : prior_variance[3] * bbox[3]);
+
+            break;
+        }
+        case DetectionOutputLayerCodeType::CENTER_SIZE:
+        {
+            const float prior_width  = prior_bbox[2] - prior_bbox[0];
+            const float prior_height = prior_bbox[3] - prior_bbox[1];
+
+            // Check if the prior width and height are right
+            ARM_COMPUTE_ERROR_ON(prior_width <= 0.f);
+            ARM_COMPUTE_ERROR_ON(prior_height <= 0.f);
+
+            const float prior_center_x = (prior_bbox[0] + prior_bbox[2]) / 2.;
+            const float prior_center_y = (prior_bbox[1] + prior_bbox[3]) / 2.;
+
+            const float decode_bbox_center_x = (variance_encoded_in_target ? bbox[0] : prior_variance[0] * bbox[0]) * prior_width + prior_center_x;
+            const float decode_bbox_center_y = (variance_encoded_in_target ? bbox[1] : prior_variance[1] * bbox[1]) * prior_height + prior_center_y;
+            const float decode_bbox_width    = (variance_encoded_in_target ? std::exp(bbox[2]) : std::exp(prior_variance[2] * bbox[2])) * prior_width;
+            const float decode_bbox_height   = (variance_encoded_in_target ? std::exp(bbox[3]) : std::exp(prior_variance[3] * bbox[3])) * prior_height;
+
+            decode_bbox[0] = (decode_bbox_center_x - decode_bbox_width / 2.f);
+            decode_bbox[1] = (decode_bbox_center_y - decode_bbox_height / 2.f);
+            decode_bbox[2] = (decode_bbox_center_x + decode_bbox_width / 2.f);
+            decode_bbox[3] = (decode_bbox_center_y + decode_bbox_height / 2.f);
+
+            break;
+        }
+        case DetectionOutputLayerCodeType::CORNER_SIZE:
+        {
+            const float prior_width  = prior_bbox[2] - prior_bbox[0];
+            const float prior_height = prior_bbox[3] - prior_bbox[1];
+
+            // Check if the prior width and height are greater than 0
+            ARM_COMPUTE_ERROR_ON(prior_width <= 0.f);
+            ARM_COMPUTE_ERROR_ON(prior_height <= 0.f);
+
+            decode_bbox[0] = prior_bbox[0] + (variance_encoded_in_target ? bbox[0] : prior_variance[0] * bbox[0]) * prior_width;
+            decode_bbox[1] = prior_bbox[1] + (variance_encoded_in_target ? bbox[1] : prior_variance[1] * bbox[1]) * prior_height;
+            decode_bbox[2] = prior_bbox[2] + (variance_encoded_in_target ? bbox[2] : prior_variance[2] * bbox[2]) * prior_width;
+            decode_bbox[3] = prior_bbox[3] + (variance_encoded_in_target ? bbox[3] : prior_variance[3] * bbox[3]) * prior_height;
+
+            break;
+        }
+        default:
+            ARM_COMPUTE_ERROR("Unsupported Detection Output Code Type.");
+    }
+
+    if(clip_bbox)
+    {
+        for(auto &d_bbox : decode_bbox)
+        {
+            d_bbox = utility::clamp(d_bbox, 0.f, 1.f);
+        }
+    }
+}
+
+/** Do non maximum suppression given bboxes and scores.
+ *
+ * @param[in]  bboxes          The input bounding boxes.
+ * @param[in]  scores          The corresponding input confidence.
+ * @param[in]  score_threshold The threshold used to filter detection results.
+ * @param[in]  nms_threshold   The threshold used in non maximum suppression.
+ * @param[in]  eta             Adaptation rate for nms threshold.
+ * @param[in]  top_k           If not -1, keep at most top_k picked indices.
+ * @param[out] indices         The kept indices of bboxes after nms.
+ *
+ */
+void ApplyNMSFast(const std::vector<NormalizedBBox> &bboxes,
+                  const std::vector<float> &scores, const float score_threshold,
+                  const float nms_threshold, const float eta, const int top_k,
+                  std::vector<int> &indices)
+{
+    ARM_COMPUTE_ERROR_ON_MSG(bboxes.size() != scores.size(), "bboxes and scores have different size.");
+
+    // Get top_k scores (with corresponding indices).
+    std::list<std::pair<float, int>> score_index_vec;
+
+    // Generate index score pairs.
+    for(size_t i = 0; i < scores.size(); ++i)
+    {
+        if(scores[i] > score_threshold)
+        {
+            score_index_vec.emplace_back(std::make_pair(scores[i], i));
+        }
+    }
+
+    // Sort the score pair according to the scores in descending order
+    score_index_vec.sort(SortScorePairDescend<int>);
+
+    // Keep top_k scores if needed.
+    const int score_index_vec_size = score_index_vec.size();
+    if(top_k > -1 && top_k < score_index_vec_size)
+    {
+        score_index_vec.resize(top_k);
+    }
+
+    // Do nms.
+    float adaptive_threshold = nms_threshold;
+    indices.clear();
+
+    while(!score_index_vec.empty())
+    {
+        const int idx  = score_index_vec.front().second;
+        bool      keep = true;
+        for(int kept_idx : indices)
+        {
+            if(keep)
+            {
+                // Compute the jaccard (intersection over union IoU) overlap between two bboxes.
+                NormalizedBBox intersect_bbox = std::array<float, 4>({ 0, 0, 0, 0 });
+                if(bboxes[kept_idx][0] > bboxes[idx][2] || bboxes[kept_idx][2] < bboxes[idx][0] || bboxes[kept_idx][1] > bboxes[idx][3] || bboxes[kept_idx][3] < bboxes[idx][1])
+                {
+                    intersect_bbox = std::array<float, 4>({ 0, 0, 0, 0 });
+                }
+                else
+                {
+                    intersect_bbox = std::array<float, 4>({ std::max(bboxes[idx][0], bboxes[kept_idx][0]), std::max(bboxes[idx][1], bboxes[kept_idx][1]), std::min(bboxes[idx][2], bboxes[kept_idx][2]), std::min(bboxes[idx][3],
+                                                            bboxes[kept_idx][3])
+                                                          });
+                }
+
+                float intersect_width  = intersect_bbox[2] - intersect_bbox[0];
+                float intersect_height = intersect_bbox[3] - intersect_bbox[1];
+
+                float overlap = 0.f;
+                if(intersect_width > 0 && intersect_height > 0)
+                {
+                    float intersect_size = intersect_width * intersect_height;
+                    float bbox1_size     = (bboxes[idx][2] < bboxes[idx][0]
+                                            || bboxes[idx][3] < bboxes[idx][1]) ?
+                                           0.f :
+                                           (bboxes[idx][2] - bboxes[idx][0]) * (bboxes[idx][3] - bboxes[idx][1]); //BBoxSize(bboxes[idx]);
+                    float bbox2_size = (bboxes[kept_idx][2] < bboxes[kept_idx][0]
+                                        || bboxes[kept_idx][3] < bboxes[kept_idx][1]) ?
+                                       0.f :
+                                       (bboxes[kept_idx][2] - bboxes[kept_idx][0]) * (bboxes[kept_idx][3] - bboxes[kept_idx][1]); // BBoxSize(bboxes[kept_idx]);
+                    overlap = intersect_size / (bbox1_size + bbox2_size - intersect_size);
+                }
+                keep = (overlap <= adaptive_threshold);
+            }
+            else
+            {
+                break;
+            }
+        }
+        if(keep)
+        {
+            indices.push_back(idx);
+        }
+        score_index_vec.erase(score_index_vec.begin());
+        if(keep && eta < 1 && adaptive_threshold > 0.5)
+        {
+            adaptive_threshold *= eta;
+        }
+    }
+}
+} // namespace
+
+CPPDetectionOutputLayer::CPPDetectionOutputLayer()
+    : _input_loc(nullptr), _input_conf(nullptr), _input_priorbox(nullptr), _output(nullptr), _info(), _num_priors(), _num(), _all_location_predictions(), _all_confidence_scores(), _all_prior_bboxes(),
+      _all_prior_variances(), _all_decode_bboxes(), _all_indices()
+{
+}
+
+void CPPDetectionOutputLayer::configure(const ITensor *input_loc, const ITensor *input_conf, const ITensor *input_priorbox, ITensor *output, DetectionOutputLayerInfo info)
+{
+    ARM_COMPUTE_ERROR_ON_NULLPTR(input_loc, input_conf, input_priorbox, output);
+    // Output auto initialization if not yet initialized
+    // Since the number of bboxes to kept is unknown before nms, the shape is set to the maximum
+    // The maximum is keep_top_k * input_loc_size[1]
+    // Each row is a 7 dimension std::vector, which stores [image_id, label, confidence, xmin, ymin, xmax, ymax]
+    const unsigned int max_size = info.keep_top_k() * (input_loc->info()->num_dimensions() > 1 ? input_loc->info()->dimension(1) : 1);
+    auto_init_if_empty(*output->info(), input_loc->info()->clone()->set_tensor_shape(TensorShape(7U, max_size)));
+
+    // Perform validation step
+    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input_loc->info(), input_conf->info(), input_priorbox->info(), output->info(), info));
+
+    _input_loc      = input_loc;
+    _input_conf     = input_conf;
+    _input_priorbox = input_priorbox;
+    _output         = output;
+    _info           = info;
+    _num_priors     = input_priorbox->info()->dimension(0) / 4;
+    _num            = (_input_loc->info()->num_dimensions() > 1 ? _input_loc->info()->dimension(1) : 1);
+
+    _all_location_predictions.resize(_num);
+    _all_confidence_scores.resize(_num);
+    _all_prior_bboxes.resize(_num_priors);
+    _all_prior_variances.resize(_num_priors);
+    _all_decode_bboxes.resize(_num);
+
+    for(int i = 0; i < _num; ++i)
+    {
+        for(int c = 0; c < _info.num_loc_classes(); ++c)
+        {
+            const int label = _info.share_location() ? -1 : c;
+            if(label == _info.background_label_id())
+            {
+                // Ignore background class.
+                continue;
+            }
+            _all_decode_bboxes[i][label].resize(_num_priors);
+        }
+    }
+    _all_indices.resize(_num);
+
+    Coordinates coord;
+    coord.set_num_dimensions(output->info()->num_dimensions());
+    output->info()->set_valid_region(ValidRegion(coord, output->info()->tensor_shape()));
+}
+
+Status CPPDetectionOutputLayer::validate(const ITensorInfo *input_loc, const ITensorInfo *input_conf, const ITensorInfo *input_priorbox, const ITensorInfo *output, DetectionOutputLayerInfo info)
+{
+    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input_loc, input_conf, input_priorbox, output, info));
+    return Status{};
+}
+
+void CPPDetectionOutputLayer::run()
+{
+    // Retrieve all location predictions.
+    retrieve_all_loc_predictions(_input_loc, _num, _num_priors, _info.num_loc_classes(), _info.share_location(), _all_location_predictions);
+
+    // Retrieve all confidences.
+    retrieve_all_conf_scores(_input_conf, _num, _num_priors, _info.num_classes(), _all_confidence_scores);
+
+    // Retrieve all prior bboxes.
+    retrieve_all_priorbox(_input_priorbox, _num_priors, _all_prior_bboxes, _all_prior_variances);
+
+    // Decode all loc predictions to bboxes
+    const bool clip_bbox = false;
+    for(int i = 0; i < _num; ++i)
+    {
+        for(int c = 0; c < _info.num_loc_classes(); ++c)
+        {
+            const int label = _info.share_location() ? -1 : c;
+            if(label == _info.background_label_id())
+            {
+                // Ignore background class.
+                continue;
+            }
+            ARM_COMPUTE_ERROR_ON_MSG(_all_location_predictions[i].find(label) == _all_location_predictions[i].end(), "Could not find location predictions for label %d.", label);
+
+            const std::vector<NormalizedBBox> &label_loc_preds = _all_location_predictions[i].find(label)->second;
+
+            const int num_bboxes = _all_prior_bboxes.size();
+            ARM_COMPUTE_ERROR_ON(_all_prior_variances[i].size() != 4);
+
+            for(int j = 0; j < num_bboxes; ++j)
+            {
+                DecodeBBox(_all_prior_bboxes[j], _all_prior_variances[j], _info.code_type(), _info.variance_encoded_in_target(), clip_bbox, label_loc_preds[j], _all_decode_bboxes[i][label][j]);
+            }
+        }
+    }
+
+    int num_kept = 0;
+
+    for(int i = 0; i < _num; ++i)
+    {
+        const LabelBBox &decode_bboxes = _all_decode_bboxes[i];
+        const std::map<int, std::vector<float>> &conf_scores = _all_confidence_scores[i];
+
+        std::map<int, std::vector<int>> indices;
+        int num_det = 0;
+        for(int c = 0; c < _info.num_classes(); ++c)
+        {
+            if(c == _info.background_label_id())
+            {
+                // Ignore background class
+                continue;
+            }
+            const int label = _info.share_location() ? -1 : c;
+            if(conf_scores.find(c) == conf_scores.end() || decode_bboxes.find(label) == decode_bboxes.end())
+            {
+                ARM_COMPUTE_ERROR("Could not find predictions for label %d.", label);
+            }
+            const std::vector<float>          &scores = conf_scores.find(c)->second;
+            const std::vector<NormalizedBBox> &bboxes = decode_bboxes.find(label)->second;
+
+            ApplyNMSFast(bboxes, scores, _info.confidence_threshold(), _info.nms_threshold(), _info.eta(), _info.top_k(), indices[c]);
+
+            num_det += indices[c].size();
+        }
+
+        int num_to_add = 0;
+        if(_info.keep_top_k() > -1 && num_det > _info.keep_top_k())
+        {
+            std::vector<std::pair<float, std::pair<int, int>>> score_index_pairs;
+            for(auto it : indices)
+            {
+                const int               label         = it.first;
+                const std::vector<int> &label_indices = it.second;
+
+                if(conf_scores.find(label) == conf_scores.end())
+                {
+                    ARM_COMPUTE_ERROR("Could not find predictions for label %d.", label);
+                }
+
+                const std::vector<float> &scores = conf_scores.find(label)->second;
+                for(auto idx : label_indices)
+                {
+                    ARM_COMPUTE_ERROR_ON(idx > static_cast<int>(scores.size()));
+                    score_index_pairs.push_back(std::make_pair(scores[idx], std::make_pair(label, idx)));
+                }
+            }
+
+            // Keep top k results per image.
+            std::sort(score_index_pairs.begin(), score_index_pairs.end(), SortScorePairDescend<std::pair<int, int>>);
+            score_index_pairs.resize(_info.keep_top_k());
+
+            // Store the new indices.
+
+            std::map<int, std::vector<int>> new_indices;
+            for(auto score_index_pair : score_index_pairs)
+            {
+                int label = score_index_pair.second.first;
+                int idx   = score_index_pair.second.second;
+                new_indices[label].push_back(idx);
+            }
+            _all_indices[i] = new_indices;
+            num_to_add      = _info.keep_top_k();
+        }
+        else
+        {
+            _all_indices[i] = indices;
+            num_to_add      = num_det;
+        }
+        num_kept += num_to_add;
+    }
+
+    //Update the valid region of the ouput to mark the exact number of detection
+    _output->info()->set_valid_region(ValidRegion(Coordinates(0, 0), TensorShape(7, num_kept)));
+
+    int count = 0;
+    for(int i = 0; i < _num; ++i)
+    {
+        const std::map<int, std::vector<float>> &conf_scores = _all_confidence_scores[i];
+        const LabelBBox &decode_bboxes = _all_decode_bboxes[i];
+        for(auto &it : _all_indices[i])
+        {
+            const int                 label     = it.first;
+            const std::vector<float> &scores    = conf_scores.find(label)->second;
+            const int                 loc_label = _info.share_location() ? -1 : label;
+            if(conf_scores.find(label) == conf_scores.end() || decode_bboxes.find(loc_label) == decode_bboxes.end())
+            {
+                // Either if there are no confidence predictions
+                // or there are no location predictions for current label.
+                ARM_COMPUTE_ERROR("Could not find predictions for the label %d.", label);
+            }
+            const std::vector<NormalizedBBox> &bboxes  = decode_bboxes.find(loc_label)->second;
+            const std::vector<int>            &indices = it.second;
+
+            for(auto idx : indices)
+            {
+                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7))))     = i;
+                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 1)))) = label;
+                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 2)))) = scores[idx];
+                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 3)))) = bboxes[idx][0];
+                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 4)))) = bboxes[idx][1];
+                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 5)))) = bboxes[idx][2];
+                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 6)))) = bboxes[idx][3];
+
+                ++count;
+            }
+        }
+    }
+}
+} // namespace arm_compute
\ No newline at end of file
