目标检测框存在内嵌情况分析与解决

news/2024/7/10 1:24:49 标签: 目标检测, 目标跟踪, 人工智能

这里写目录标题

  • 问题描述
  • 原因分析与解决方法:
  • 后续及思考
  • 参考文档

问题描述

目标检测模型输出的检测框存在内嵌情况。

在这里插入图片描述


原因分析与解决方法:

根据经验,第一感觉是后处理nms部分出了问题。来看下对应的代码:

static float CalcIou(const vector<float> &box1, const vector<float> &box2)
{
    float area1 = box1[6];
    float area2 = box2[6];
    float xx1 = max(box1[0], box2[0]);
    float yy1 = max(box1[1], box2[1]);
    float xx2 = min(box1[2], box2[2]);
    float yy2 = min(box1[3], box2[3]);
    float w = max(0.0f, xx2 - xx1 + 1);
    float h = max(0.0f, yy2 - yy1 + 1);
    float inter = w * h;
    float ovr = inter /(area1 + area2 - inter);
    return ovr;
}

static void MulticlassNms(vector<vector<float>>& bboxes, const vector<vector<float>>& vaildBox, float nmsThr)
{
    for (auto &item : vaildBox) { /* score, xcenter, ycenter, w, h, classId */
        float boxXCenter = item[XCENTER_IDX];
        float boxYCenter = item[YCENTER_IDX];
        float boxWidth = item[W_IDX];
        float boxHeight = item[H_IDX];

        float x1 = (boxXCenter - boxWidth / 2);
        float y1 = (boxYCenter - boxHeight / 2);
        float x2 = (boxXCenter + boxWidth / 2);
        float y2 = (boxYCenter + boxHeight / 2);
        float area = (x2 - x1 + 1) * (y2 - y1 + 1);
        bool keep = true;
        /* lx, ly, rx, ry, score, class id, area */
        vector<float> bbox {x1, y1, x2, y2, item[SCORE_IDX], item[CLSAA_ID_IDX], area};
        for (size_t j = 0; j < bboxes.size(); j++) {
            if (CalcIou(bbox, bboxes[j]) > nmsThr) {
                keep = false;
                break;
            }
        }
        if (keep) {
            bboxes.push_back(bbox);
        }
    }
}

目前分析最可能的原因是nmsnmsThr设置过大,没能滤除重叠检测框,原来nmsThr设置的为0.45,现调整为0.1
检测框内嵌情况基本消失:
在这里插入图片描述


后续及思考

先给个结论,综合的看下各个Loss函数的不同点::
IOU_Loss:主要考虑检测框和目标框重叠面积
GIOU_Loss:在IOU的基础上,解决边界框不重合时的问题。
DIOU_Loss:在IOU和GIOU的基础上,考虑边界框中心点距离的信息。
CIOU_Loss:在DIOU的基础上,考虑边界框宽高比的尺度信息。
此项目中用的是基本的IOU,在推理性能足够的情况下,可以考虑使用DIOU,下面也给出使用DIOUnms代码:

static float CalcDiou(const vector<float>& box1, const vector<float>& box2) {
    float x1 = min(box1[0], box2[0]);
    float y1 = min(box1[1], box2[1]);
    float x2 = max(box1[2], box2[2]);
    float y2 = max(box1[3], box2[3]);
    
    float c_x1 = (box1[0] + box1[2]) / 2.0;
    float c_y1 = (box1[1] + box1[3]) / 2.0;
    float c_x2 = (box2[0] + box2[2]) / 2.0;
    float c_y2 = (box2[1] + box2[3]) / 2.0;
    
    float dist_center = sqrt((c_x1 - c_x2) * (c_x1 - c_x2) + (c_y1 - c_y2) * (c_y1 - c_y2));
    
    float w = max(0.0f, x2 - x1);
    float h = max(0.0f, y2 - y1);
    
    float intersection = w * h;
    float area1 = (box1[2] - box1[0]) * (box1[3] - box1[1]);
    float area2 = (box2[2] - box2[0]) * (box2[3] - box2[1]);
    
    float union_area = area1 + area2 - intersection;
    
    float diou = intersection / union_area - dist_center * dist_center / (union_area * union_area);
    
    return diou;
}

static void MulticlassNms(vector<vector<float>>& bboxes, const vector<vector<float>>& vaildBox, float nmsThr)
{
    for (auto &item : vaildBox) { /* score, xcenter, ycenter, w, h, classId */
        float boxXCenter = item[XCENTER_IDX];
        float boxYCenter = item[YCENTER_IDX];
        float boxWidth = item[W_IDX];
        float boxHeight = item[H_IDX];

        float x1 = (boxXCenter - boxWidth / 2);
        float y1 = (boxYCenter - boxHeight / 2);
        float x2 = (boxXCenter + boxWidth / 2);
        float y2 = (boxYCenter + boxHeight / 2);
        float area = (x2 - x1 + 1) * (y2 - y1 + 1);
        bool keep = true;

        vector<float> bbox {x1, y1, x2, y2, item[SCORE_IDX], item[CLSAA_ID_IDX], area};
        for (size_t j = 0; j < bboxes.size(); j++) {
            if (CalcDiou(bbox, bboxes[j]) > nmsThr) {
                keep = false;
                break;
            }
        }
        if (keep) {
            bboxes.push_back(bbox);
        }
    }
}

有读者会有疑问,这里为什么不用CIOU_nms,而用DIOU_nms?
答:因为CIOU_loss,是在DIOU_loss的基础上,添加的影响因子,包含groundtruth标注框的信息,在训练时用于回归。
但在测试过程中,并没有groundtruth的信息,不用考虑影响因子,因此直接用DIOU_nms即可。

参考文档

https://blog.csdn.net/nan355655600/article/details/106246625


http://www.niftyadmin.cn/n/5197681.html

相关文章

Sql Server 2017主从配置之:发布订阅

使用发布订阅模式搭建Sql Server 2017主从同步&#xff0c;类似事件通知机制&#xff0c;基本可以做到准实时同步&#xff0c;可以同时做到一对多的数据同步。 不过发布订阅模式&#xff0c;只能同时数据&#xff0c;不能同步表结构。在创建发布的时候&#xff0c;需要选择需要…

Hive安装配置 - 本地模式

文章目录 一、Hive运行模式二、安装配置本地模式Hive&#xff08;一&#xff09;安装配置MySQL1、删除系统自带的MariaDB2、上传MySQL组件到虚拟机3、在主节点上安装MySQL组件4、在主节点上配置MySQL&#xff08;1&#xff09;查看MySQL服务状态&#xff08;2&#xff09;查看M…

【狂神说Java】redis

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;【狂神说Java】 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c…

算法分析与设计课后练习21

某工业生产部门根据国家计划的安排,拟将某种高效率的5台机器,分别分配给A,B,C三个工厂,各工厂在获得不同数量的这种机器后,可以为国家盈利如下表所示。请找出一种5台机器的分配方式,使得这5台机器盈利最大。 使用动态规划,令dp[i][j]=max(dp[i-1][j-k]+profit[i][k])…

常见树种(贵州省):005竹类

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、毛竹 …

已超1000+测试员分享!Python自动化测试案例实战

随着企业对测试工程师的能力要求日渐增长&#xff0c;对我们每一位测试工程师而言既是压力也是提升的动力&#xff0c;不提升就意味着没有出路&#xff0c;没有发展&#xff01;我们职业发展的命运是靠自己的能力来把握的&#xff0c;而不是一味的惧怕高要求&#xff0c;惧怕难…

AnyTXT Searcher:本地文件内容搜索神器如何搭建与远程访问

文章目录 前言1. AnyTXT Searcher1.1 下载安装AnyTXT Searcher 2. 下载安装注册cpolar3. AnyTXT Searcher设置和操作3.1 AnyTXT结合cpolar—公网访问搜索神器3.2 公网访问测试 4. 固定连接公网地址 前言 你是否遇到过这种情况&#xff0c;异地办公或者不在公司&#xff0c;想找…

Linux C 基于tcp多线程在线聊天室

多线程在线聊天室 概述客户端服务端 概述 客户端实现了判单用户登录结果、防止单回车字符发送、保存和显示历史聊天记录&#xff08;仅自己&#xff09;、退出聊天室功能。   服务端实现了验证用户是否已经存在&#xff08;支持最大64用户连接&#xff09;支持广播用户进入退…