NMS 非极大值抑制C++实现

//修改版
//把需要删除的,标记起来,单独删除
//重叠比例超过阈值,那么框就删掉不会被保留。这个阈值越小,越容易被满足,相叠框越容易被删掉。
//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-

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值