std::tuple Processor::detect()

in models/01_YoloV5/01_Pytorch/processing_cpp/src/processor.cc [125:150]


std::tuple<vecf,vecf,vecf> Processor::detect(std::vector<vecf>& pred, float threshold, float iou_threshold ) { 
    for (size_t i=0; i < pred.size(); ++i ) {
        std::for_each(pred[i].begin(), pred[i].end(), sigmoid);
        auto sliceA = xt::strided_view(pred[i], {xt::ellipsis(), xt::range(0,2) });
        auto sliceB = xt::strided_view(pred[i], {xt::ellipsis(), xt::range(2,4) });
        sliceA = (sliceA * 2.0 - 0.5 + grids[i]) * strides[i];
        sliceB = xt::pow(sliceB * 2.0, 2) * xt::strided_view(anchorGrid, {i, xt::ellipsis()});
        pred[i].reshape({1, -1, featureCount});
    } // for
    // Workaround to avoid concatenate and improve performance
    vecf predictions = xt::zeros<float>({pred[0].size() + pred[1].size() + pred[2].size()});
    std::copy(pred[0].begin(), pred[0].end(), predictions.begin());
    std::copy(pred[1].begin(), pred[1].end(), predictions.begin()+pred[0].size());
    std::copy(pred[2].begin(), pred[2].end(), predictions.begin()+pred[0].size()+pred[1].size());
    predictions.reshape({1,-1,numClasses + 5});

    auto sliceC = xt::strided_view(predictions, {xt::ellipsis(), 4});
    vecs idx = xt::ravel_indices(xt::argwhere(sliceC > threshold), predictions.shape());
    vecf resp = xt::view(predictions, xt::all(), xt::keep(idx), xt::all());

    if (resp.size() > 0) {
        return getDetections(xt::squeeze(resp), iou_threshold);
    } else {
        throw std::invalid_argument("No object found!");
    } // else
}