目标检测网络中大框包含小框的问题,非极大值抑制算法(Non-MaximumSuppress。。。

更新时间:2023-06-24 11:36:41 阅读: 评论:0

⽬标检测⽹络中⼤框包含⼩框的问题,⾮极⼤值抑制算法(Non-
MaximumSuppress。。。
⽬标检测系列⽂章
前⾔
NMS⼀直是Object Detection很难绕开的步骤,本⼈的⽬标检测⽹络中遇到⼀个⽬标检测输出⼤框包含⼩框的问题如下图,(⼤概率是数据没搞好,但是数据多很难查出是哪写数据)。于是对nms做了⼀个修改。此⽅法可直接加在任何⽬标检测⽹络原版nms后⾯
这种情况下原版nms是⽆法过滤掉⽬标内的⼩框的。
⼀、NMS介绍
NMS 算法的⼤致过程:每轮选取置信度最⼤的 Bounding Box(简称 BBox,有时也会看到⽤ Pc,Possible Candidates 代替讲解的),接着关注所有剩下的 BBox 中与选取的 BBox 有着⾼重叠(IOU)的,它们将在这⼀轮被抑制。这⼀轮选取的 BBox 会被保留输出,且不会在下⼀轮出现。接着开始下⼀轮,重复上述过程:选取置信度最⼤ BBox ,抑制⾼ IOU BBox。
NMS 算法流程:这是⼀般⽂章中介绍的 NMS,⽐较难懂。但实际上 NMS 的实现反⽽简单很多。
⼆、NMS优化⼩框代码实现
这种⽅法必须外⾯加⼀层循环每类单独进⾏nms,才不会吧不同类别的框过滤掉
#include<iostream>
#include<vector>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
static void sort(int n,const vector<float> x, vector<int> indices)
{
int i, j;
for(i =0; i < n; i++)
for(j = i +1; j < n; j++)
{
if(x[indices[j]]> x[indices[i]])
{
//float x_tmp = x[i];
int index_tmp = indices[i];
//x[i] = x[j];
indices[i]= indices[j];
徐浩鑫//x[j] = x_tmp;
indices[j]= index_tmp;
}
}
}
int nonMaximumSuppression(int numBoxes,const vector<Point> points,const vector<Point> oppositePoints,
const vector<float> score,float overlapThreshold,int& numBoxesOut, vector<Point>& pointsOut,
vector<Point>& oppositePointsOut, vector<float> scoreOut)
{
{
// 实现检测出的矩形窗⼝的⾮极⼤值抑制nms
// numBoxes:窗⼝数⽬// points:窗⼝左上⾓坐标点// oppositePoints:窗⼝右下⾓坐标点// score:窗⼝得分
// overlapThreshold:重叠阈值控制// numBoxesOut:输出窗⼝数⽬// pointsOut:输出窗⼝左上⾓坐
标点
// oppositePointsOut:输出窗⼝右下⾓坐标点// scoreOut:输出窗⼝得分
int i, j, index;
vector<float>box_area(numBoxes);// 定义窗⼝⾯积变量并分配空间
vector<int>indices(numBoxes);// 定义窗⼝索引并分配空间
vector<int>is_suppresd(numBoxes);// 定义是否抑制表标志并分配空间
// 初始化indices、is_suppersd、box_area信息
for(i =0; i < numBoxes; i++)
{
indices[i]= i;
is_suppresd[i]=0;
形容专业的成语
box_area[i]=(float)((oppositePoints[i].x - points[i].x +1)*(oppositePoints[i].y - points[i].y +1));
}
// 对输⼊窗⼝按照分数⽐值进⾏排序,排序后的编号放在indices中
sort(numBoxes, score, indices);
for(i =0; i < numBoxes; i++)// 循环所有窗⼝
{
if(!is_suppresd[indices[i]])// 判断窗⼝是否被抑制
{
for(j = i +1; j < numBoxes; j++)// 循环当前窗⼝之后的窗⼝
{
if(!is_suppresd[indices[j]])// 判断窗⼝是否被抑制
{
int x1max =max(points[indices[i]].x, points[indices[j]].x);// 求两个窗⼝左上⾓x坐标最⼤值
int x2min =min(oppositePoints[indices[i]].x, oppositePoints[indices[j]].x);// 求两个窗⼝右下⾓x坐标最⼩值int y1max =max(points[indices[i]].y, points[indices[j]].y);// 求两个窗⼝左上⾓y坐标最⼤值
int y2min =min(oppositePoints[indices[i]].y, oppositePoints[indices[j]].y);// 求两个窗⼝右下⾓y坐标最⼩值int overlapWidth = x2min - x1max;// 计算两矩形重叠的宽度
int overlapHeight = y2min - y1max;// 计算两矩形重叠的⾼度
float overlap = overlapWidth * overlapHeight;
float area_i =(oppositePoints[indices[i]].x - points[indices[i]].x)*(oppositePoints[indices[i]].y - points[indices[i]].y);
float area_j =(oppositePoints[indices[j]].x - points[indices[j]].x)*(oppositePoints[indices[j]].y - points[indices[j]].y);
if(overlapWidth >0&& overlapHeight >0)
{
//float overlapPart = (overlapWidth * overlapHeight) / box_area[indices[j]];    // 计算重叠的⽐率
float overlapPart = overlap /(area_i + area_j - overlap);
//if (overlapPart > overlapThreshold)  // 判断重叠⽐率是否超过重叠阈值
//{
// is_suppresd[indices[j]] = 1;    // 将窗⼝j标记为抑制
//}
/*if (overlap == min(area_i, area_j))  //只会过滤掉⼤框内部⼩框
{
is_suppresd[indices[j]] = 1;
}*/
第2页if(area_i > area_j)//能过滤掉⼤框内部⼩框,或者是上下超界的⼩框
{
if(overlapWidth ==(oppositePoints[indices[j]].x - points[indices[j]].x))
{
is_suppresd[indices[j]]=1;
}
}
if(area_j > area_i)//能过滤掉⼤框内部⼩框,或者是上下超界的⼩框
{
六年级上册第二单元作文if(overlapWidth ==(oppositePoints[indices[i]].x - points[indices[i]].x))
{
12月英语怎么说
is_suppresd[indices[j]]=1;
}
}
}
}
}
}
}
}
numBoxesOut =0;// 初始化输出窗⼝数⽬0
for(i =0; i < numBoxes; i++)
{
if(!is_suppresd[i]) numBoxesOut++;// 统计输出窗⼝数⽬
}
index =0;高中地理教案
for(i =0; i < numBoxes; i++)// 遍历所有输⼊窗⼝
{
if(!is_suppresd[indices[i]])// 将未发⽣抑制的窗⼝信息保存到输出信息中
{
pointsOut.push_back(Point(points[indices[i]].x, points[indices[i]].y));
oppositePointsOut.push_back(Point(oppositePoints[indices[i]].x, oppositePoints[indices[i]].y));
scoreOut.push_back(score[indices[i]]);
index++;
}
}
return true;
}
int main()
{
Mat image = Mat::zeros(600,600, CV_8UC3);
int numBoxes =4;
vector<Point>points(numBoxes);
vector<Point>oppositePoints(numBoxes);
vector<float>score(numBoxes);
points[0]=Point(100,100); oppositePoints[0]=Point(500,500); score[0]=0.99;
points[1]=Point(300,110); oppositePoints[1]=Point(350,480); score[1]=0.9;
points[2]=Point(220,220); oppositePoints[2]=Point(550,550); score[2]=0.98;
points[3]=Point(120,90); oppositePoints[3]=Point(200,510); score[3]=0.98;
float overlapThreshold =0.3;
int numBoxesOut;
vector<Point> pointsOut;
vector<Point> oppositePointsOut;
vector<float> scoreOut;
nonMaximumSuppression(numBoxes, points, oppositePoints, score, overlapThreshold, numBoxesOut, pointsOut, oppositePointsOut, scoreOut); for(int i =0; i<numBoxes; i++)
{
rectangle(image, points[i], oppositePoints[i],Scalar(0,255,255),6);
char text[20];
//_cprintf(text, "%f", score[i]);
//putText(image, score[i].c_str(), points[i], FONT_HERSHEY_COMPLEX, 1, Scalar(0, 255, 255));
做家务的作文
}
掌声作文600字
cout << numBoxesOut << endl;
for(int i =0; i<numBoxesOut; i++)
{
rectangle(image, pointsOut[i], oppositePointsOut[i],Scalar(0,0,255),2);
}
imshow("result", image);
waitKey();
return0;
}
如下图,没有画红线框极为已经过滤掉了

本文发布于:2023-06-24 11:36:41,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1052702.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:重叠   输出   是否   排序   抑制   作文   检测   信息
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图