|
|
@ -58,6 +58,83 @@ void NMSBoxes(const std::vector<RotatedRect>& bboxes, const std::vector<float>& |
|
|
|
NMSFast_(bboxes, scores, score_threshold, nms_threshold, eta, top_k, indices, rotatedRectIOU); |
|
|
|
NMSFast_(bboxes, scores, score_threshold, nms_threshold, eta, top_k, indices, rotatedRectIOU); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void softNMSBoxes(const std::vector<Rect>& bboxes, |
|
|
|
|
|
|
|
const std::vector<float>& scores, |
|
|
|
|
|
|
|
std::vector<float>& updated_scores, |
|
|
|
|
|
|
|
const float score_threshold, |
|
|
|
|
|
|
|
const float nms_threshold, |
|
|
|
|
|
|
|
std::vector<int>& indices, |
|
|
|
|
|
|
|
size_t top_k, |
|
|
|
|
|
|
|
const float sigma, |
|
|
|
|
|
|
|
SoftNMSMethod method) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CV_Assert_N(bboxes.size() == scores.size(), score_threshold >= 0, |
|
|
|
|
|
|
|
nms_threshold >= 0, sigma >= 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
indices.clear(); |
|
|
|
|
|
|
|
updated_scores.clear(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::pair<float, size_t> > score_index_vec(scores.size()); |
|
|
|
|
|
|
|
for (size_t i = 0; i < scores.size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
score_index_vec[i].first = scores[i]; |
|
|
|
|
|
|
|
score_index_vec[i].second = i; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const auto score_cmp = [](const std::pair<float, size_t>& a, const std::pair<float, size_t>& b) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return a.first == b.first ? a.second > b.second : a.first < b.first; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
top_k = top_k == 0 ? scores.size() : std::min(top_k, scores.size()); |
|
|
|
|
|
|
|
ptrdiff_t start = 0; |
|
|
|
|
|
|
|
while (indices.size() < top_k) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto it = std::max_element(score_index_vec.begin() + start, score_index_vec.end(), score_cmp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float bscore = it->first; |
|
|
|
|
|
|
|
size_t bidx = it->second; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bscore < score_threshold) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
indices.push_back(static_cast<int>(bidx)); |
|
|
|
|
|
|
|
updated_scores.push_back(bscore); |
|
|
|
|
|
|
|
std::swap(score_index_vec[start], *it); // first start elements are chosen
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = start + 1; i < scores.size(); ++i) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
float& bscore_i = score_index_vec[i].first; |
|
|
|
|
|
|
|
const size_t bidx_i = score_index_vec[i].second; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bscore_i < score_threshold) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float overlap = rectOverlap(bboxes[bidx], bboxes[bidx_i]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (method) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case SoftNMSMethod::SOFTNMS_LINEAR: |
|
|
|
|
|
|
|
if (overlap > nms_threshold) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bscore_i *= 1.f - overlap; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case SoftNMSMethod::SOFTNMS_GAUSSIAN: |
|
|
|
|
|
|
|
bscore_i *= exp(-(overlap * overlap) / sigma); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
CV_Error(Error::StsBadArg, "Not supported SoftNMS method."); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
++start; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CV__DNN_INLINE_NS_END |
|
|
|
CV__DNN_INLINE_NS_END |
|
|
|
}// dnn
|
|
|
|
}// dnn
|
|
|
|
}// cv
|
|
|
|
}// cv
|
|
|
|