目标检测面试-nms
1、python语言下:
def nms(self, dets, scores):
# 这一代码来源于Faster RCNN项目
""""Pure Python NMS baseline."""
x1 = dets[:, 0] #xmin
y1 = dets[:, 1] #ymin
x2 = dets[:, 2] #xmax
y2 = dets[:, 3] #ymax
areas = (x2 - x1) * (y2 - y1) # bbox的宽w和高h
order = scores.argsort()[::-1] # 按照降序对bbox的得分进行排序
keep = [] # 用于保存经过筛的最终bbox结果
while order.size > 0:
i = order[0] # 得到最高的那个bbox
keep.append(i)
xx1 = np.maximum(x1[i], x1[order[1:]])
yy1 = np.maximum(y1[i], y1[order[1:]])
xx2 = np.minimum(x2[i], x2[order[1:]])
yy2 = np.minimum(y2[i], y2[order[1:]])
w = np.maximum(1e-28, xx2 - xx1)
h = np.maximum(1e-28, yy2 - yy1)
inter = w * h
# Cross Area / (bbox + particular area - Cross Area)
ovr = inter / (areas[i] + areas[order[1:]] - inter)
#reserve all the boundingbox whose ovr less than thresh
inds = np.where(ovr <= self.nms_thresh)[0]
order = order[inds + 1]
return keep
2、C++下:
#include<bits/stdc++.h>
using namespace std;
typedef struct Bbox
{
int xmin;
int ymin;
int xmax;
int ymax;
float score;
}Bbox;
bool sort_score(Bbox box1,Bbox box2)
{
return (box1.score > box2.score);
}
float iou(Bbox box1,Bbox box2)
{
int x1 = max(box1.xmin,box2.xmin);
int y1 = max(box1.ymin,box2.ymin);
int x2 = min(box1.xmax,box2.xmax);
int y2 = min(box1.ymax,box2.ymax);
int w1 = box1.xmax - box1.xmin, h1 = box1.ymax - box1.ymin;
int w2 = box2.xmax - box2.xmin, h2 = box2.ymax - box2.ymin;
float inter_area = (x2 - x1) * (y2 - y1);
float iou = inter_area/(w1*h1 + w2*h2-inter_area);
return iou;
}
//方法1
vector<Bbox> nms(vector<Bbox>&vec_boxs,float threshold)
{
sort(vec_boxs.begin(),vec_boxs.end(),sort_score);
vector<bool>del(vec_boxs.size(),false);
for(int i =0; i<vec_boxs.size();i++)
{
for (int j =0;j<vec_boxs.size();j++)
{
float iou_value =iou(vec_boxs[i],vec_boxs[j]);
if(iou_value>threshold) del[j]=true;
}
}
vector<Bbox>results;
for(const auto i :del)
{
if(!del[i]) results.push_back(vec_box[i]);
}
return results;
}
//方法2 这种执行效率更高
vector<Bbox> nms(vector<Bbox>&vec_boxs,float threshold)
{
vector<Bbox>results;
while(vec_boxs.size() > 0)
{
sort(vec_boxs.begin(),vec_boxs.end(),sort_score);
results.push_back(vec_boxs[0]);
for(int i =0;i <vec_boxs.size()-1;i++)
{
float iou_value =iou(vec_boxs[0],vec_boxs[i+1]);
if (iou_value >threshold) vec_boxs.erase(vec_boxs[i+1]);
}
vec_boxs.erase(vec_boxs[0]);
}
return results;
}
1-python版:https://www.zhihu.com/column/c_1364967262269693952
2-C++版:https://blog.csdn.net/qq_32582681/article/details/81352758
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。