45
45
#include < float.h>
46
46
#include < string>
47
47
#include < caffe.pb.h>
48
+ #include " ../nms.inl.hpp"
48
49
49
50
namespace cv
50
51
{
@@ -61,6 +62,8 @@ static inline bool SortScorePairDescend(const std::pair<float, T>& pair1,
61
62
return pair1.first > pair2.first ;
62
63
}
63
64
65
+ static inline float caffe_box_overlap (const caffe::NormalizedBBox& a, const caffe::NormalizedBBox& b);
66
+
64
67
} // namespace
65
68
66
69
class DetectionOutputLayerImpl : public DetectionOutputLayer
@@ -308,7 +311,8 @@ class DetectionOutputLayerImpl : public DetectionOutputLayer
308
311
LabelBBox::const_iterator label_bboxes = decodeBBoxes.find (label);
309
312
if (label_bboxes == decodeBBoxes.end ())
310
313
CV_ErrorNoReturn_ (cv::Error::StsError, (" Could not find location predictions for label %d" , label));
311
- ApplyNMSFast (label_bboxes->second , scores, _confidenceThreshold, _nmsThreshold, 1.0 , _topK, indices[c]);
314
+ NMSFast_ (label_bboxes->second , scores, _confidenceThreshold, _nmsThreshold, 1.0 , _topK,
315
+ indices[c], util::caffe_box_overlap);
312
316
numDetections += indices[c].size ();
313
317
}
314
318
if (_keepTopK > -1 && numDetections > (size_t )_keepTopK)
@@ -619,75 +623,6 @@ class DetectionOutputLayerImpl : public DetectionOutputLayer
619
623
}
620
624
}
621
625
622
- // Do non maximum suppression given bboxes and scores.
623
- // Inspired by Piotr Dollar's NMS implementation in EdgeBox.
624
- // https://goo.gl/jV3JYS
625
- // bboxes: a set of bounding boxes.
626
- // scores: a set of corresponding confidences.
627
- // score_threshold: a threshold used to filter detection results.
628
- // nms_threshold: a threshold used in non maximum suppression.
629
- // top_k: if not -1, keep at most top_k picked indices.
630
- // indices: the kept indices of bboxes after nms.
631
- static void ApplyNMSFast (const std::vector<caffe::NormalizedBBox>& bboxes,
632
- const std::vector<float >& scores, const float score_threshold,
633
- const float nms_threshold, const float eta, const int top_k,
634
- std::vector<int >& indices)
635
- {
636
- CV_Assert (bboxes.size () == scores.size ());
637
-
638
- // Get top_k scores (with corresponding indices).
639
- std::vector<std::pair<float , int > > score_index_vec;
640
- GetMaxScoreIndex (scores, score_threshold, top_k, score_index_vec);
641
-
642
- // Do nms.
643
- float adaptive_threshold = nms_threshold;
644
- indices.clear ();
645
- while (score_index_vec.size () != 0 ) {
646
- const int idx = score_index_vec.front ().second ;
647
- bool keep = true ;
648
- for (int k = 0 ; k < (int )indices.size () && keep; ++k) {
649
- const int kept_idx = indices[k];
650
- float overlap = JaccardOverlap<true >(bboxes[idx], bboxes[kept_idx]);
651
- keep = overlap <= adaptive_threshold;
652
- }
653
- if (keep)
654
- indices.push_back (idx);
655
- score_index_vec.erase (score_index_vec.begin ());
656
- if (keep && eta < 1 && adaptive_threshold > 0.5 ) {
657
- adaptive_threshold *= eta;
658
- }
659
- }
660
- }
661
-
662
- // Get max scores with corresponding indices.
663
- // scores: a set of scores.
664
- // threshold: only consider scores higher than the threshold.
665
- // top_k: if -1, keep all; otherwise, keep at most top_k.
666
- // score_index_vec: store the sorted (score, index) pair.
667
- static void GetMaxScoreIndex (const std::vector<float >& scores, const float threshold, const int top_k,
668
- std::vector<std::pair<float , int > >& score_index_vec)
669
- {
670
- CV_DbgAssert (score_index_vec.empty ());
671
- // Generate index score pairs.
672
- for (size_t i = 0 ; i < scores.size (); ++i)
673
- {
674
- if (scores[i] > threshold)
675
- {
676
- score_index_vec.push_back (std::make_pair (scores[i], i));
677
- }
678
- }
679
-
680
- // Sort the score pair according to the scores in descending order
681
- std::stable_sort (score_index_vec.begin (), score_index_vec.end (),
682
- util::SortScorePairDescend<int >);
683
-
684
- // Keep top_k scores if needed.
685
- if (top_k > -1 && top_k < (int )score_index_vec.size ())
686
- {
687
- score_index_vec.resize (top_k);
688
- }
689
- }
690
-
691
626
// Compute the jaccard (intersection over union IoU) overlap between two bboxes.
692
627
template <bool normalized>
693
628
static float JaccardOverlap (const caffe::NormalizedBBox& bbox1,
@@ -733,6 +668,11 @@ class DetectionOutputLayerImpl : public DetectionOutputLayer
733
668
}
734
669
};
735
670
671
+ float util::caffe_box_overlap (const caffe::NormalizedBBox& a, const caffe::NormalizedBBox& b)
672
+ {
673
+ return DetectionOutputLayerImpl::JaccardOverlap<true >(a, b);
674
+ }
675
+
736
676
const std::string DetectionOutputLayerImpl::_layerName = std::string(" DetectionOutput" );
737
677
738
678
Ptr<DetectionOutputLayer> DetectionOutputLayer::create (const LayerParams ¶ms)
0 commit comments