#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
using std::cin;
struct BoundingBox{
float x1;
float y1;
float x2;
float y2;
float score;
};
struct CmpBoundingBox {
bool operator()(const BoundingBox &b1, const BoundingBox &b2) {
return b1.score < b2.score; //增序
}
};
void nms(std::vector<BoundingBox> &boxes,
float threshold,
std::vector<BoundingBox> &filterOutBoxs)
{
// input check
uint32_t boxsSize = boxes.size();
filterOutBoxs.clear();
if (boxsSize == 0) {
cout << "the inputs boxes size is empty!";
return;
}
// sort the boundingBox
sort(boxes.begin(), boxes.end(), CmpBoundingBox());
// pick the box
uint32_t lastBoxIdex;
float overLop;
float area1, area2, infer_area;
float infer_x1, infer_y1, infer_x2, infer_y2;
float w, h = 0;
while (!boxes.empty()) {
lastBoxIdex = boxes.size() - 1;
auto tempBox = boxes[lastBoxIdex];
filterOutBoxs.push_back(boxes[lastBoxIdex]);
boxes.erase(boxes.begin() + lastBoxIdex);
area1 = (tempBox.x2 - tempBox.x1 + 1) * (tempBox.y2 - tempBox.y1 + 1);;
std::vector<BoundingBox>::iterator boxIter = boxes.begin();
while (boxIter != boxes.end())
{
infer_x1 = std::max(boxIter->x1, tempBox.x1);
infer_y1 = std::max(boxIter->y1, tempBox.y1);
infer_x2 = std::min(boxIter->x2, tempBox.x2);
infer_y2 = std::min(boxIter->y2, tempBox.y2);
w = std::max(infer_x2 - infer_x1 + 1, 0.0f);
h = std::max(infer_y2 - infer_y1 + 1, 0.0f);
infer_area = w * h;
area2 = (boxIter->x2 - boxIter->x1 + 1) * (boxIter->y2 - boxIter->y1 + 1);
overLop = infer_area / (area1 + area2 - infer_area);
if (overLop > threshold) {
boxIter = boxes.erase(boxIter);
} else {
boxIter++;
}
}
}
}
int main(void)
{
std::vector<BoundingBox> bbox;
bbox.push_back(BoundingBox{ 0, 0, 1, 1, 0.9 });
bbox.push_back(BoundingBox{ 0, 0, 1, 2, 0.8 });
bbox.push_back(BoundingBox{ 0, 0, 1, 3, 0.7 });
bbox.push_back(BoundingBox{ 0, 0, 1, 4, 0.6 });
bbox.push_back(BoundingBox{ 0, 0, 1, 5, 0.5 });
std::vector<BoundingBox> outBox;
nms(bbox, 0.4, outBox);
return 0;
}