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
}