首页 > 编程语言 >昇腾 - AscendCL C++应用开发 目标检测中的非极大值抑制NMS和计算候选边界框之间的交并比IOU

昇腾 - AscendCL C++应用开发 目标检测中的非极大值抑制NMS和计算候选边界框之间的交并比IOU

时间:2024-08-21 19:51:02浏览次数:7  
标签:std NMS min max IOU float AscendCL inter box1

昇腾 - AscendCL C++应用开发 目标检测中的非极大值抑制(NMS,Non-Maximum Suppression)涉及计算候选边界框之间的交并比(IOU,Intersection over Union)

flyfish

结构体 BBox: 定义了一个边界框的数据结构,包含中心坐标、宽高、置信度分数、类别索引和输出索引。
函数 IOU: 计算两个边界框之间的交并比。
函数 NMS: 实现非极大值抑制算法,通过逐步移除与当前最佳边界框的IOU超过给定阈值的边界框来筛选出最佳边界框集合。

#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
struct BBox {
    float x;         // 边界框中心的x坐标
    float y;         // 边界框中心的y坐标
    float w;         // 边界框的宽度
    float h;         // 边界框的高度
    float score;     // 置信度分数
    int classIndex;  // 类别索引
    int index;       // 输出缓冲区的索引
};

// 计算两个边界框的交并比(IOU)
float IOU(const BBox& box1, const BBox& box2) {
    // 计算每个边界框的左上角和右下角坐标
    float x1_min = box1.x - box1.w / 2.0f;
    float y1_min = box1.y - box1.h / 2.0f;
    float x1_max = box1.x + box1.w / 2.0f;
    float y1_max = box1.y + box1.h / 2.0f;

    float x2_min = box2.x - box2.w / 2.0f;
    float y2_min = box2.y - box2.h / 2.0f;
    float x2_max = box2.x + box2.w / 2.0f;
    float y2_max = box2.y + box2.h / 2.0f;

    // 计算相交区域的左上角和右下角坐标
    float inter_x_min = std::max(x1_min, x2_min);
    float inter_y_min = std::max(y1_min, y2_min);
    float inter_x_max = std::min(x1_max, x2_max);
    float inter_y_max = std::min(y1_max, y2_max);

    // 计算相交区域的宽度和高度
    float inter_w = std::max(0.0f, inter_x_max - inter_x_min);
    float inter_h = std::max(0.0f, inter_y_max - inter_y_min);

    // 计算相交面积
    float inter_area = inter_w * inter_h;

    // 计算每个边界框的面积
    float box1_area = box1.w * box1.h;
    float box2_area = box2.w * box2.h;

    // 计算交并比(IOU)
    float iou = inter_area / (box1_area + box2_area - inter_area);
    return iou;
}

// 实现NMS算法
std::vector<BBox> NMS(const std::vector<BBox>& boxes, float iouThreshold) {
    // 按置信度分数从高到低排序
    std::vector<BBox> sortedBoxes = boxes;
    std::sort(sortedBoxes.begin(), sortedBoxes.end(), [](const BBox& a, const BBox& b) {
        return a.score > b.score;
    });

    std::vector<BBox> result;

    // 遍历每一个候选框
    while (!sortedBoxes.empty()) {
        // 选择置信度最高的框
        BBox bestBox = sortedBoxes.front();
        result.push_back(bestBox);

        // 移除与最佳框IOU大于阈值的所有框
        sortedBoxes.erase(std::remove_if(sortedBoxes.begin(), sortedBoxes.end(),
                                         [&](const BBox& box) {
                                             return IOU(bestBox, box) > iouThreshold;
                                         }),
                          sortedBoxes.end());
    }

    return result;
}

int main() {
    // 示例边界框
    std::vector<BBox> boxes = {
        {100.0, 100.0, 50.0, 50.0, 0.9, 0, 0},
        {102.0, 102.0, 50.0, 50.0, 0.85, 0, 1},
        {200.0, 200.0, 50.0, 50.0, 0.75, 1, 2},
        {220.0, 220.0, 50.0, 50.0, 0.7, 1, 3}
    };

    // 进行NMS
    float iouThreshold = 0.5;
    std::vector<BBox> filteredBoxes = NMS(boxes, iouThreshold);

    // 输出结果
    for (const auto& box : filteredBoxes) {
        std::cout << "Box: (" << box.x << ", " << box.y << "), w=" << box.w
                  << ", h=" << box.h << ", score=" << box.score
                  << ", classIndex=" << box.classIndex << std::endl;
    }

    return 0;
}

输出

Box: (100, 100), w=50, h=50, score=0.9, classIndex=0
Box: (200, 200), w=50, h=50, score=0.75, classIndex=1
Box: (220, 220), w=50, h=50, score=0.7, classIndex=1

移除与最佳框IOU大于阈值的所有框

  1. std::remove_if :首先调用 std::remove_if 将所有不符合条件的元素移到容器的前面,并将符合条件的元素移到后面。此时容器的大小并没有变化,且不符合条件的元素仍然存在于容器的内存中。
auto newEnd = std::remove_if(container.begin(), container.end(), condition);
  1. erase :接着,调用 erase 使用 std::remove_if 返回的迭代器范围来删除从“逻辑末尾”到实际末尾的元素。最终,这个操作会减少容器的大小,并真正删除那些符合条件的元素。
container.erase(newEnd, container.end());

这种组合方式可以避免多次调用 erase 来删除每个满足条件的元素,因为删除单个元素的代价较高,而 std::remove_if 只会遍历一次容器,并通过 erase 进行一次性删除。

例子

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 移除所有偶数
    auto newEnd = std::remove_if(vec.begin(), vec.end(), [](int x) {
        return x % 2 == 0;  // 条件:为偶数时移除
    });

    // 真正从容器中删除它们
    vec.erase(newEnd, vec.end());

    // 输出结果
    for (int x : vec) {
        std::cout << x << " ";
    }
    return 0;
}

标签:std,NMS,min,max,IOU,float,AscendCL,inter,box1
From: https://blog.csdn.net/flyfish1986/article/details/141365655

相关文章

  • Object Detection: Non-Maximum Suppression (NMS)
    ObjectDetection:Non-MaximumSuppression(NMS)https://kikaben.com/object-detection-non-maximum-suppression/ObjectdetectionmodelslikeYOLOv5andSSDpredictobjects’locationsbygeneratingboundingboxes(showninbluerectanglesbelow).However,......
  • The English names of various berries All In One
    TheEnglishnamesofvariousberriesAllInOneallkindsofberriesnamesberry浆果常见berry种类strawberry草莓......
  • Golang文件操作秘籍:ioutil包的终极指南
    Golang文件操作秘籍:ioutil包的终极指南在Go语言的世界中,文件操作是一项基本而常见的任务。Go标准库中的ioutil包提供了一些简便的方法来执行常见的I/O操作,包括文件的读写。本文将深入探讨如何使用ioutil包进行文件读写操作,并提供详细的代码示例,帮助你快速掌握这一技能。io......
  • Buuctf-Mysterious另类逆向题解
    下载发现是一个exe可执行文件双击运行,输入密码123456没有任何反应,当然没反应,密码肯定不对请出IDApro,我这里用IDAProv8.3演示,把exe文件拖拽到IDA打开按shift+F12快捷键搜索字符串我们发现第二行有可疑字符串,有flag嫌疑,双击上面的welldonewelldone里“Buff3r_0......
  • iOS的AudioUnit音效框架技术详解
    iOS的AVAudioUnit提供的音效包括:混响、延迟、均衡器、失真、变速、变调等。按照类型划分为AudioEffect和TimeEffect,其中AudioEffect包括混响、延迟、均衡器和失真,而TimeEffect主要是变速、变调。一、音效应用层框架音效的应用层框架以AVAudioUnit作为核心抽象类,如下图所......
  • 洛谷 CF896C Willem, Chtholly and Seniorious之珂朵莉树板子
    洛谷CF896C题解传送锚点摸鱼环节Willem,ChthollyandSeniorious题面翻译【题面】请你写一种奇怪的数据结构,支持:\(1\)\(l\)\(r\)\(x\):将\([l,r]\)区间所有数加上\(x\)\(2\)\(l\)\(r\)\(x\):将\([l,r]\)区间所有数改成\(x\)\(3\)\(l\)\(r\)\(x\):输出将\(......
  • 人工智能深度学习系列—深入探索IoU Loss及其变种:目标检测与分割的精度优化利器
    人工智能深度学习系列—深度解析:交叉熵损失(Cross-EntropyLoss)在分类问题中的应用人工智能深度学习系列—深入解析:均方误差损失(MSELoss)在深度学习中的应用与实践人工智能深度学习系列—深入探索KL散度:度量概率分布差异的关键工具人工智能深度学习系列—探索余弦相似度损......
  • siebel server 启动时报Cleaning up previous execution of【转】
    恢复sibel某个环境整个SIEBELschema数据后,再启动sibelserver时,有时会hang死掉,也不生成任何日志,解决:这种情况往往需要reboot这台siebelserver所在的服务器,再启动siebelserver一般就能正常起来了。起来的提示信息中会多一句提示:cleaninguppreviousexecutionof.....,如下:[s......
  • NMS(non maximum suppression)非极大值抑制
    参考学习:算法精讲-预测阶段后处理-NMS非极大值抑制_哔哩哔哩_bilibili以YOLOv1的模型来讲,预测阶段后处理就是把每个boundingbox中的每个种类的值算出全概率,再对比boundingbox中同种类物品,先设定一个阈值,把boundingbox中同种类全概率低于阈值的算为0,再进行一次降序排序,通过遍历......
  • nms_bev函数
     defnms_bev(boxes,scores,thresh,pre_max_size=None,post_max_size=None):"""NMSfunctionGPUimplementation(forBEVboxes).TheoverlapoftwoboxesforIoUcalculationisdefinedastheexactoverlappingareaofthetwo......