//修改版
//把需要删除的,标记起来,单独删除
//重叠比例超过阈值,那么框就删掉不会被保留。这个阈值越小,越容易被满足,相叠框越容易被删掉。
//ok 的
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
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_s(std::vector<BoundingBox>& boxes, float threshold, std::vector<BoundingBox>& outputBoxes)
{
// input check
uint32_t boxsSize = boxes.size();
outputBoxes.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 overlap;
float area1, area2, inter_area;
float inter_x1, inter_y1, inter_x2, inter_y2;
float w, h = 0;
while (!boxes.empty())
{
lastBoxIdex = boxes.size() - 1;
auto tempBox = boxes[lastBoxIdex];
outputBoxes.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())
{
inter_x1 = std::max(boxIter->x1, tempBox.x1);
inter_y1 = std::max(boxIter->y1, tempBox.y1);
inter_x2 = std::min(boxIter->x2, tempBox.x2);
inter_y2 = std::min(boxIter->y2, tempBox.y2);
w = std::max(inter_x2 - inter_x1 + 1, 0.0f);
h = std::max(inter_y2 - inter_y1 + 1, 0.0f);
inter_area = w * h;
area2 = (boxIter->x2 - boxIter->x1 + 1) * (boxIter->y2 - boxIter->y1 + 1);
overlap = inter_area / (area1 + area2 - inter_area);
if (overlap > threshold)
{
boxIter = boxes.erase(boxIter);
}
else
{
boxIter++;
}
}
}
}
int main()
{
std::vector<BoundingBox> bbox;
bbox.push_back(BoundingBox{ 0, 0, 100, 100, 0.9 });
bbox.push_back(BoundingBox{ 0, 0, 50, 50, 0.8 });
bbox.push_back(BoundingBox{ 20, 20, 50, 50, 0.7 });
bbox.push_back(BoundingBox{ 2, 2, 100, 100, 0.6 });
bbox.push_back(BoundingBox{ 200, 200, 100, 50, 0.5 });
std::vector<BoundingBox> outBox;
nms_s(bbox, 0.5, outBox);
printf("bbox.size=%zd outBox.size=%lld\n", bbox.size(), outBox.size());
return 0;
}
//https://blog.csdn.net/qq_28818443/article/details/102810258?depth_1-
// //https://blog.csdn.net/qq_30587589/article/details/84098333?depth_1-