Commit fb44c7ba authored by Davis King's avatar Davis King

Added box_intersection_over_union() and also renamed the class members of

test_box_overlap so they are less confusing and vague.
parent f0dff5fc
...@@ -10,27 +10,51 @@ ...@@ -10,27 +10,51 @@
namespace dlib namespace dlib
{ {
// ----------------------------------------------------------------------------------------
inline double box_intersection_over_union (
const drectangle& a,
const drectangle& b
)
{
const double inner = a.intersect(b).area();
if (inner == 0)
return 0;
const double outer = (a+b).area();
return inner/outer;
}
// ----------------------------------------------------------------------------------------
inline double box_intersection_over_union (
const rectangle& a,
const rectangle& b
)
{
return box_intersection_over_union(drectangle(a),drectangle(b));
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
class test_box_overlap class test_box_overlap
{ {
public: public:
test_box_overlap ( test_box_overlap (
) : match_thresh(0.5), overlap_thresh(1.0) ) : iou_thresh(0.5), percent_covered_thresh(1.0)
{} {}
explicit test_box_overlap ( explicit test_box_overlap (
double match_thresh_, double iou_thresh_,
double overlap_thresh_ = 1.0 double percent_covered_thresh_ = 1.0
) : match_thresh(match_thresh_), overlap_thresh(overlap_thresh_) ) : iou_thresh(iou_thresh_), percent_covered_thresh(percent_covered_thresh_)
{ {
// make sure requires clause is not broken // make sure requires clause is not broken
DLIB_ASSERT(0 <= match_thresh && match_thresh <= 1 && DLIB_ASSERT(0 <= iou_thresh && iou_thresh <= 1 &&
0 <= overlap_thresh && overlap_thresh <= 1, 0 <= percent_covered_thresh && percent_covered_thresh <= 1,
"\t test_box_overlap::test_box_overlap(match_thresh, overlap_thresh)" "\t test_box_overlap::test_box_overlap(iou_thresh, percent_covered_thresh)"
<< "\n\t Invalid inputs were given to this function " << "\n\t Invalid inputs were given to this function "
<< "\n\t match_thresh: " << match_thresh << "\n\t iou_thresh: " << iou_thresh
<< "\n\t overlap_thresh: " << overlap_thresh << "\n\t percent_covered_thresh: " << percent_covered_thresh
<< "\n\t this: " << this << "\n\t this: " << this
); );
...@@ -46,29 +70,29 @@ namespace dlib ...@@ -46,29 +70,29 @@ namespace dlib
return false; return false;
const double outer = (a+b).area(); const double outer = (a+b).area();
if (inner/outer > match_thresh || if (inner/outer > iou_thresh ||
inner/a.area() > overlap_thresh || inner/a.area() > percent_covered_thresh ||
inner/b.area() > overlap_thresh) inner/b.area() > percent_covered_thresh)
return true; return true;
else else
return false; return false;
} }
double get_overlap_thresh ( double get_percent_covered_thresh (
) const ) const
{ {
return overlap_thresh; return percent_covered_thresh;
} }
double get_match_thresh ( double get_iou_thresh (
) const ) const
{ {
return match_thresh; return iou_thresh;
} }
private: private:
double match_thresh; double iou_thresh;
double overlap_thresh; double percent_covered_thresh;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -78,8 +102,8 @@ namespace dlib ...@@ -78,8 +102,8 @@ namespace dlib
std::ostream& out std::ostream& out
) )
{ {
serialize(item.get_match_thresh(), out); serialize(item.get_iou_thresh(), out);
serialize(item.get_overlap_thresh(), out); serialize(item.get_percent_covered_thresh(), out);
} }
inline void deserialize ( inline void deserialize (
...@@ -87,10 +111,10 @@ namespace dlib ...@@ -87,10 +111,10 @@ namespace dlib
std::istream& in std::istream& in
) )
{ {
double overlap_thresh, match_thresh; double percent_covered_thresh, iou_thresh;
deserialize(match_thresh, in); deserialize(iou_thresh, in);
deserialize(overlap_thresh, in); deserialize(percent_covered_thresh, in);
item = test_box_overlap(match_thresh, overlap_thresh); item = test_box_overlap(iou_thresh, percent_covered_thresh);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -99,8 +123,8 @@ namespace dlib ...@@ -99,8 +123,8 @@ namespace dlib
const std::vector<std::vector<rectangle> >& rects const std::vector<std::vector<rectangle> >& rects
) )
{ {
double max_overlap = 0; double max_pcov = 0;
double max_match_score = 0; double max_iou_score = 0;
for (unsigned long i = 0; i < rects.size(); ++i) for (unsigned long i = 0; i < rects.size(); ++i)
{ {
for (unsigned long j = 0; j < rects[i].size(); ++j) for (unsigned long j = 0; j < rects[i].size(); ++j)
...@@ -109,29 +133,29 @@ namespace dlib ...@@ -109,29 +133,29 @@ namespace dlib
{ {
const rectangle a = rects[i][j]; const rectangle a = rects[i][j];
const rectangle b = rects[i][k]; const rectangle b = rects[i][k];
const double match_score = (a.intersect(b)).area()/(double)(a+b).area(); const double iou_score = (a.intersect(b)).area()/(double)(a+b).area();
const double overlap_a = (a.intersect(b)).area()/(double)(a).area(); const double pcov_a = (a.intersect(b)).area()/(double)(a).area();
const double overlap_b = (a.intersect(b)).area()/(double)(b).area(); const double pcov_b = (a.intersect(b)).area()/(double)(b).area();
if (match_score > max_match_score) if (iou_score > max_iou_score)
max_match_score = match_score; max_iou_score = iou_score;
if (overlap_a > max_overlap) if (pcov_a > max_pcov)
max_overlap = overlap_a; max_pcov = pcov_a;
if (overlap_b > max_overlap) if (pcov_b > max_pcov)
max_overlap = overlap_b; max_pcov = pcov_b;
} }
} }
} }
// Relax these thresholds very slightly. We do this because on some systems the // Relax these thresholds very slightly. We do this because on some systems the
// boxes that generated the max values erroneously trigger a box overlap match // boxes that generated the max values erroneously trigger a box overlap iou even
// even though their overlap and match values are *equal* to the thresholds but not // though their percent covered and iou values are *equal* to the thresholds but
// greater. That is, sometimes when double values get moved around they change // not greater. That is, sometimes when double values get moved around they change
// their values slightly, so this avoids the problems that can create. // their values slightly, so this avoids the problems that can create.
max_match_score = std::min(1.0000001*max_match_score, 1.0); max_iou_score = std::min(1.0000001*max_iou_score, 1.0);
max_overlap = std::min(1.0000001*max_overlap, 1.0); max_pcov = std::min(1.0000001*max_pcov, 1.0);
return test_box_overlap(max_match_score, max_overlap); return test_box_overlap(max_iou_score, max_pcov);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -8,6 +8,30 @@ ...@@ -8,6 +8,30 @@
namespace dlib namespace dlib
{ {
// ----------------------------------------------------------------------------------------
inline double box_intersection_over_union (
const drectangle& a,
const drectangle& b
);
/*!
ensures
- returns area of the intersection of a and b divided by (a+b).area(). If both
boxes are empty then returns 0.
!*/
// ----------------------------------------------------------------------------------------
inline double box_intersection_over_union (
const rectangle& a,
const rectangle& b
);
/*!
ensures
- returns area of the intersection of a and b divided by (a+b).area(). If both
boxes are empty then returns 0.
!*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
class test_box_overlap class test_box_overlap
...@@ -28,21 +52,21 @@ namespace dlib ...@@ -28,21 +52,21 @@ namespace dlib
); );
/*! /*!
ensures ensures
- #get_match_thresh() == 0.5 - #get_iou_thresh() == 0.5
- #get_overlap_thresh() == 1.0 - #get_percent_covered_thresh() == 1.0
!*/ !*/
explicit test_box_overlap ( explicit test_box_overlap (
double match_thresh, double iou_thresh,
double overlap_thresh = 1.0 double percent_covered_thresh = 1.0
); );
/*! /*!
requires requires
- 0 <= match_thresh <= 1 - 0 <= iou_thresh <= 1
- 0 <= overlap_thresh <= 1 - 0 <= percent_covered_thresh <= 1
ensures ensures
- #get_match_thresh() == match_thresh - #get_iou_thresh() == iou_thresh
- #get_overlap_thresh() == overlap_thresh - #get_percent_covered_thresh() == percent_covered_thresh
!*/ !*/
bool operator() ( bool operator() (
...@@ -52,31 +76,30 @@ namespace dlib ...@@ -52,31 +76,30 @@ namespace dlib
/*! /*!
ensures ensures
- returns true if a and b overlap "enough". This is defined precisely below. - returns true if a and b overlap "enough". This is defined precisely below.
- if (a.intersect(b).area()/(a+b).area() > get_match_thresh() || - if (a.intersect(b).area()/(a+b).area() > get_iou_thresh() ||
a.intersect(b).area()/a.area() > get_overlap_thresh() || a.intersect(b).area()/a.area() > get_percent_covered_thresh() ||
a.intersect(b).area()/b.area() > get_overlap_thresh() ) then a.intersect(b).area()/b.area() > get_percent_covered_thresh() ) then
- returns true - returns true
- else - else
- returns false - returns false
!*/ !*/
double get_match_thresh ( double get_iou_thresh (
) const; ) const;
/*! /*!
ensures ensures
- returns the threshold used to determine if two rectangles match. - returns the threshold used to determine if two rectangle's intersection
Note that the match score varies from 0 to 1 and only becomes 1 over union value is big enough to be considered a match. Note that the
when two rectangles are identical. iou score varies from 0 to 1 and only becomes 1 when two rectangles are
identical.
!*/ !*/
double get_overlap_thresh ( double get_percent_covered_thresh (
) const; ) const;
/*! /*!
ensures ensures
- returns the threshold used to determine if two rectangles overlap. This - returns the threshold used to determine if two rectangles overlap. This
value is the percent of a rectangle's area covered by another rectangle. value is the percent of a rectangle's area covered by another rectangle.
!*/ !*/
}; };
...@@ -110,7 +133,7 @@ namespace dlib ...@@ -110,7 +133,7 @@ namespace dlib
that is consistent with the given set of sets of rectangles. that is consistent with the given set of sets of rectangles.
- To be precise, this function finds and returns a test_box_overlap object - To be precise, this function finds and returns a test_box_overlap object
TBO such that: TBO such that:
- TBO.get_match_thresh() and TBO.get_overlap_thresh() are as small - TBO.get_iou_thresh() and TBO.get_percent_covered_thresh() are as small
as possible such that the following conditions are satisfied. as possible such that the following conditions are satisfied.
- for all valid i: - for all valid i:
- for all distinct rectangles A and B in rects[i]: - for all distinct rectangles A and B in rects[i]:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment