Repository: opencv/opencv
File: modules/dnn/src/layers/nonmaxsuppression_layer.cpp (C++)

Code before:

                if (rects.empty())
                    continue;

                std::vector<Rect2d> rects2d; rects2d.reserve(rects.size());
                for (const Rect2f& rf : rects) {
                    rects2d.emplace_back((double)rf.x, (double)rf.y, (double)rf.width, (double)rf.height);
                }
                std::vector<int> keep;
                NMSBoxes(rects2d, scores, /*score_threshold*/ scoreThr, /*nms_threshold*/ iouThr, keep, 1.f,
                                  0);
                if (maxOut > 0 && (int)keep.size() > maxOut)
                    keep.resize(maxOut);

                auto& local = tripletsPerBC[taskIdx];
                local.reserve(keep.size());
                for (int kept : keep) {
                    const int globalIdx = globalIndices[kept];
                    local.push_back({(long long)b, (long long)c, (long long)globalIdx});
                }
            }
        });

        int K = 0;
        for (int t = 0; t < tasks; ++t) K += (int)tripletsPerBC[t].size();
        outputs_arr.getMatRef(0).create(2, std::array<int,2>{K, 3}.data(), CV_64S);
        auto* out = outputs_arr.getMatRef(0).ptr<long long>();
        std::vector<int> offsets(tasks + 1, 0);
        for (int t = 0; t < tasks; ++t)
            offsets[t + 1] = offsets[t] + (int)tripletsPerBC[t].size() * 3;
        cv::parallel_for_(cv::Range(0, tasks), [&](const cv::Range& r){
            for (int t = r.start; t < r.end; ++t) {
                long long* dst = out + offsets[t];
                const auto& v = tripletsPerBC[t];
                for (const auto& trip : v) {
                    *dst++ = trip[0]; *dst++ = trip[1]; *dst++ = trip[2];
                }
            }
        });
    }

private:
    int   centerPointBox = 0;
    int   defaultMaxOut = 0;
    float defaultIouThr = 0.f;
    float defaultScoreThr = 0.f;
};

Ptr<NonMaxSuppressionLayer> NonMaxSuppressionLayer::create(const LayerParams& params) {
    return Ptr<NonMaxSuppressionLayer>(new NonMaxSuppressionLayerImpl(params));
}

Review comment (suggestion):
```
outputs_arr.getMatRef(0).create(K, 3, CV_64S);
```

Code after:
            CV_Assert(outs.size() == 1);
            outs[0].create(K, 3, CV_64S);
            outMat = outs[0];
        } else if (outKind == _InputArray::STD_VECTOR_UMAT) {
            std::vector<UMat> uouts;
            outputs_arr.getUMatVector(uouts);
            CV_Assert(uouts.size() == 1);
            uouts[0].fit(MatShape({K, 3}), CV_64S);
            outMat = uouts[0].getMat(ACCESS_WRITE);
        } else {
            outputs_arr.getMatRef(0).create(K, 3, CV_64S);
            outMat = outputs_arr.getMatRef(0);
        }

        auto* out = outMat.ptr<int64_t>();
        std::vector<int> offsets(tasks + 1, 0);
        for (int t = 0; t < tasks; ++t)
            offsets[t + 1] = offsets[t] + (int)tripletsPerBC[t].size() * 3;
        parallel_for_(Range(0, tasks), [&](const Range& r){
            for (int t = r.start; t < r.end; ++t) {
                int64_t* dst = out + offsets[t];
                const auto& v = tripletsPerBC[t];
                for (const auto& trip : v) {
                    *dst++ = trip[0]; *dst++ = trip[1]; *dst++ = trip[2];
                }
            }
        });
    }

private:
    void run(const Mat& boxesBlob, const Mat& scoresBlob, int maxOut, float iouThr, float scoreThr,
             std::vector<std::vector<Vec<int64_t,3>>>& tripletsPerBC) const
    {
        const int B = boxesBlob.size[0];
        const int N = boxesBlob.size[1];
        const int C = scoresBlob.size[1];

        const int tasks = B * C;
        tripletsPerBC.clear();
        tripletsPerBC.resize(tasks);

        parallel_for_(Range(0, tasks), [&](const Range& r){
            std::vector<Rect2f> rects;
            std::vector<float> scores;
            std::vector<int> globalIndices;
            rects.reserve(N); scores.reserve(N); globalIndices.reserve(N);
            std::vector<Rect2d> rects2d;
            std::vector<int> keep;
            rects2d.reserve(N);
            keep.reserve(N);