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

news/2024/12/29 11:45:32/

这里写目录标题

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

问题描述

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

在这里插入图片描述


原因分析与解决方法:

根据经验,第一感觉是后处理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.ppmy.cn/news/1229661.html

相关文章

CLIP浅谈

CLIP论文地址&#xff1a;Learning Transferable Visual Models From Natural Language Supervision CLIP代码地址&#xff1a;https://github.com/openai/CLIP 简介 CLIP是OpenAI在2021年2月发表的一篇文章&#xff0c;它的主要贡献有以下2点&#xff1a; 1&#xff09;将图…

Django 入门学习总结5

修改polls/detail.html文件&#xff0c;写一个表单&#xff1a; <form action"{% url polls:vote question.id %}" method"post"> {% csrf_token %} <fieldset> <legend><h1>{{ question.question_text }}</h…

xss漏洞挖掘

xss漏洞挖掘 以xss-challenge第二关为例 输入123 查看网页源代码 发现value值原样返回 手动挖掘 此处发现尖括号和双引号闭合完整&#xff0c;因此可以直接使用<script>alert(/xss/)</script>测试 发现提交过后标签内容被双引号闭合进去了 因此此处需要将标签…

python:list和dict的基本操作实例

python&#xff1a;list和dict的基本操作实例 今天我们来谈谈Python中list和dict的使用方法。这两种数据结构在Python中非常常见&#xff0c;掌握它们的使用方法对于编写高效的代码非常重要。 首先我们来看看list的使用。在下面的例子中&#xff0c;我们有一个名为ori_list的…

小程序中如何(批量)打印订单的小票、标签、发货单和电子面单

在小程序中可以实现打印订单小票、标签、发货单和电子面单&#xff0c;以及进行批量选择打印。下面具体介绍。 在打印订单之前&#xff0c;需要在小程序管理员后台->打印设置处&#xff0c;添加对应的打印机。打印机支持云打印和本地打印二种模式&#xff0c;云打印是指打印…

OpenCV入门7——OpenCV中的滤波器(包括低通滤波与高通滤波,其中低通滤波用于降噪,而高通滤波用于边缘检测)

文章目录 图像滤波卷积相关概念锚点 实战图像卷积Blur an image with a 2d convolution matrix 方盒滤波与均值滤波高斯滤波中值滤波双边滤波高通滤波—索贝尔算子高通滤波—沙尔算子高通滤波—拉普拉斯算子边缘检测Canny 图像滤波 卷积核滤波器 卷积相关概念 锚点 锚点…

【Q1—45min】

1.epoll除了边沿触发还有什么&#xff1f;与select区别. epoll 是Linux平台下的一种特有的多路复用IO实现方式&#xff0c;与传统的 select 相比&#xff0c;epoll 在性能上有很大的提升。 epoll是一种当文件描述符的内核缓冲区非空的时候&#xff0c;发出可读信号进行通知&…

Theory behind GAN

假如要生成一些人脸图&#xff0c;实际上就是想要找到一个分布&#xff0c;从这个分布内sample出来的图片像是人脸&#xff0c;分布之外生成的就不像人脸。而GAN要做的就是找到这个distribution。 在GAN之前用的是Maximum Likelihood Estimation。 Maximum Likelihood Estimat…