非极大值抑制NMS算法c++版本

非极大值抑制NMS算法c++版本

简介

非极大值抑制NMS算法 缩写NMS,全称 non maximum suppression 。常用于计算机视觉中的边缘检测、物体识别等。

给出一张图片和上面许多物体检测的候选框(即每个框可能都代表某种物体),但是这些框很可能有互相重叠的部分,我们要做的就是只保留最优的框。

NMS的作用:去掉detection任务重复的检测框。

算法流程

假设有N个框,每个框被分类器计算得到的分数为Si, 1<=i<=N。

0、建造一个存放待处理候选框的集合H,初始化为包含全部N个框;

建造一个存放最优框的集合M,初始化为空集。

1、将所有集合 H 中的框进行排序,选出分数最高的框 m,从集合 H 移到集合 M;

2、遍历集合 H 中的框,分别与框 m 计算交并比(Interection-over-union,IoU),如果高于某个阈值(一般为0~0.5),则认为此框与 m 重叠,将此框从集合 H 中去除。

3、回到第1步进行迭代,直到集合 H 为空。集合 M 中的框为我们所需。

需要优化的参数:

IoU 的阈值是一个可优化的参数,一般范围为0~0.5,可以使用交叉验证来选择最优的参数。

非极大值抑制NMS算法c++版本

typedef struct FaceInfo {
    float score;//置信度
    int x[2];
    int y[2];//框左上和右下的坐标点
    float area;//框的面积
    float regreCoord[4];//4个坐标的修正信息,返回的是框的比例
    int landmark[10];//人脸的5个特征点
} FaceInfo;

bool cmpScore(FaceInfo x, FaceInfo y)
{
    if (x.score > y.score)
        return true;
    else
        return false;
}

float calcIOU(FaceInfo box1, FaceInfo box2, string mode)
{
    int maxX = max(box1.x[0], box2.x[0]);
    int maxY = max(box1.y[0], box2.y[0]);
    int minX = min(box1.x[1], box2.x[1]);
    int minY = min(box1.y[1], box2.y[1]);//得到重叠部分的左上和右下的两个坐标点
    int width = ((minX - maxX + 1) > 0) ? (minX - maxX + 1) : 0;
    int height = ((minY - maxY + 1) > 0) ? (minY - maxY + 1) : 0;//+1防止为0,
    int inter = width * height;//重叠部分面积
    if (!mode.compare("union"))
        return float(inter) / (box1.area + box2.area - float(inter));
    else if (!mode.compare("min"))
        return float(inter) / (box1.area < box2.area ? box1.area : box2.area);
    else
        return 0;
}

void doNms(vector<FaceInfo> &bboxs, float nms_thresh, string mode)
{
    if (bboxs.empty())
        return;
    sort(bboxs.begin(), bboxs.end(), cmpScore);//将候选框按照置信度排序
    for (int i = 0; i < bboxs.size(); i++)//总的
        if (bboxs[i].score > 0)
            for (int j = i + 1; j < bboxs.size(); j++)
                if (bboxs[j].score > 0)//判断当前候选框是否被抑制
                {
                    float iou = calcIOU(bboxs[i], bboxs[j], mode);//计算正交比
                    if (iou > nms_thresh)//nms_thresh为阈值
                        bboxs[j].score = 0;//将该候选框设置为抑制
                }
    for (auto it = bboxs.begin(); it != bboxs.end();)
        if ((*it).score == 0)
            bboxs.erase(it);//清除被抑制的候选框
        else
            it++;
}
首先,YOLOv8是不存在的,我猜测您可能想问的是YOLOv3或YOLOv4。而NMS非极大值抑制的缩写,是指在目标检测算法中用于去除重叠框的一种技术。 下面是一个简单的C++伪代码,用于实现YOLOv3或YOLOv4中的NMS过程: ``` // 定义一个用于存储检测结果的结构体 struct DetectionResult { float x, y, w, h, score; }; // 定义一个用于比较两个检测结果得分的函数 bool compare_detection_results(const DetectionResult& a, const DetectionResult& b) { return a.score > b.score; } // 定义一个用于计算两个矩形框的IOU(交并比)的函数 float calculate_iou(const DetectionResult& a, const DetectionResult& b) { float left = std::max(a.x - a.w / 2, b.x - b.w / 2); float right = std::min(a.x + a.w / 2, b.x + b.w / 2); float top = std::max(a.y - a.h / 2, b.y - b.h / 2); float bottom = std::min(a.y + a.h / 2, b.y + b.h / 2); float intersection = std::max(0.f, right - left) * std::max(0.f, bottom - top); float union_area = a.w * a.h + b.w * b.h - intersection; return intersection / union_area; } // 定义一个用于执行NMS的函数 void nms(std::vector<DetectionResult>& detection_results, float iou_threshold) { // 按照得分从高到低排序 std::sort(detection_results.begin(), detection_results.end(), compare_detection_results); // 循环遍历每个检测结果 for (int i = 0; i < detection_results.size(); i++) { if (detection_results[i].score == 0) continue; // 循环遍历当前检测结果之后的所有检测结果 for (int j = i + 1; j < detection_results.size(); j++) { if (calculate_iou(detection_results[i], detection_results[j]) > iou_threshold) { // 如果两个检测结果的IOU大于阈值,则将得分较低的那个检测结果的得分置为0 detection_results[j].score = 0; } } } } ``` 以上代码仅供参考,实际的实现可能会有所不同,具体实现方式可能因模型和框架而异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值