NMS非极大值抑制的原理与代码实现
来源:互联网 发布:java的webservice 编辑:程序博客网 时间:2024/06/05 20:14
原理
对于Bounding Box的列表B及其对应的置信度S,采用下面的计算方式.选择具有最大score的检测框M,将其从B集合中移除并加入到最终的检测结果D中.通常将B中剩余检测框中与M的IoU大于阈值Nt的框从B中移除.重复这个过程,直到B为空。
实现步骤
(1)将所有框的得分排序,选中最高分及其对应的框
(2)遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。
(3)从未处理的框中继续选一个得分最高的,重复上述过程。
实现代码
MATLAB
%% NMS:non maximum suppressionfunction pick = nms(boxes,threshold,type)% boxes: m x 5,表示有m个框,5列分别是[x1 y1 x2 y2 score]% threshold: IOU阈值% type:IOU阈值的定义类型 % 输入为空,则直接返回 if isempty(boxes) pick = []; return; end % 依次取出左上角和右下角坐标以及分类器得分(置信度) x1 = boxes(:,1); y1 = boxes(:,2); x2 = boxes(:,3); y2 = boxes(:,4); s = boxes(:,5); % 计算每一个框的面积 area = (x2-x1+1) .* (y2-y1+1); %将得分升序排列 [vals, I] = sort(s); %初始化 pick = s*0; counter = 1; % 循环直至所有框处理完成 while ~isempty(I) last = length(I); %当前剩余框的数量 i = I(last);%选中最后一个,即得分最高的框 pick(counter) = i; counter = counter + 1; %计算相交面积 xx1 = max(x1(i), x1(I(1:last-1))); yy1 = max(y1(i), y1(I(1:last-1))); xx2 = min(x2(i), x2(I(1:last-1))); yy2 = min(y2(i), y2(I(1:last-1))); w = max(0.0, xx2-xx1+1); h = max(0.0, yy2-yy1+1); inter = w.*h; %不同定义下的IOU if strcmp(type,'Min') %重叠面积与最小框面积的比值 o = inter ./ min(area(i),area(I(1:last-1))); else %交集/并集 o = inter ./ (area(i) + area(I(1:last-1)) - inter); end %保留所有重叠面积小于阈值的框,留作下次处理 I = I(find(o<=threshold)); end pick = pick(1:(counter-1));end
Python
import numpy as npcimport numpy as npcdef inline np.float32_t max(np.float32_t a, np.float32_t b): return a if a >= b else bcdef inline np.float32_t min(np.float32_t a, np.float32_t b): return a if a <= b else bdef cpu_soft_nms(np.ndarray[float, ndim=2] boxes, float sigma=0.5, float Nt=0.3, float threshold=0.001, unsigned int method=0): cdef unsigned int N = boxes.shape[0] cdef float iw, ih, box_area cdef float ua cdef int pos = 0 cdef float maxscore = 0 cdef int maxpos = 0 cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ov for i in range(N): maxscore = boxes[i, 4] maxpos = i tx1 = boxes[i,0] ty1 = boxes[i,1] tx2 = boxes[i,2] ty2 = boxes[i,3] ts = boxes[i,4] pos = i + 1 # get max box while pos < N: if maxscore < boxes[pos, 4]: maxscore = boxes[pos, 4] maxpos = pos pos = pos + 1 # add max box as a detection boxes[i,0] = boxes[maxpos,0] boxes[i,1] = boxes[maxpos,1] boxes[i,2] = boxes[maxpos,2] boxes[i,3] = boxes[maxpos,3] boxes[i,4] = boxes[maxpos,4] # swap ith box with position of max box boxes[maxpos,0] = tx1 boxes[maxpos,1] = ty1 boxes[maxpos,2] = tx2 boxes[maxpos,3] = ty2 boxes[maxpos,4] = ts tx1 = boxes[i,0] ty1 = boxes[i,1] tx2 = boxes[i,2] ty2 = boxes[i,3] ts = boxes[i,4] pos = i + 1 # NMS iterations, note that N changes if detection boxes fall below threshold while pos < N: x1 = boxes[pos, 0] y1 = boxes[pos, 1] x2 = boxes[pos, 2] y2 = boxes[pos, 3] s = boxes[pos, 4] area = (x2 - x1 + 1) * (y2 - y1 + 1) iw = (min(tx2, x2) - max(tx1, x1) + 1) if iw > 0: ih = (min(ty2, y2) - max(ty1, y1) + 1) if ih > 0: ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) ov = iw * ih / ua #iou between max box and detection box if method == 1: # linear if ov > Nt: weight = 1 - ov else: weight = 1 elif method == 2: # gaussian weight = np.exp(-(ov * ov)/sigma) else: # original NMS if ov > Nt: weight = 0 else: weight = 1 boxes[pos, 4] = weight*boxes[pos, 4] # if box score falls below threshold, discard the box by swapping with last box # update N if boxes[pos, 4] < threshold: boxes[pos,0] = boxes[N-1, 0] boxes[pos,1] = boxes[N-1, 1] boxes[pos,2] = boxes[N-1, 2] boxes[pos,3] = boxes[N-1, 3] boxes[pos,4] = boxes[N-1, 4] N = N - 1 pos = pos - 1 pos = pos + 1 keep = [i for i in range(N)] return keepdef cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh): cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0] cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1] cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2] cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3] cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4] cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1) cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1] cdef int ndets = dets.shape[0] cdef np.ndarray[np.int_t, ndim=1] suppressed = \ np.zeros((ndets), dtype=np.int) # nominal indices cdef int _i, _j # sorted indices cdef int i, j # temp variables for box i's (the box currently under consideration) cdef np.float32_t ix1, iy1, ix2, iy2, iarea # variables for computing overlap with box j (lower scoring box) cdef np.float32_t xx1, yy1, xx2, yy2 cdef np.float32_t w, h cdef np.float32_t inter, ovr keep = [] for _i in range(ndets): i = order[_i] if suppressed[i] == 1: continue keep.append(i) ix1 = x1[i] iy1 = y1[i] ix2 = x2[i] iy2 = y2[i] iarea = areas[i] for _j in range(_i + 1, ndets): j = order[_j] if suppressed[j] == 1: continue xx1 = max(ix1, x1[j]) yy1 = max(iy1, y1[j]) xx2 = min(ix2, x2[j]) yy2 = min(iy2, y2[j]) w = max(0.0, xx2 - xx1 + 1) h = max(0.0, yy2 - yy1 + 1) inter = w * h ovr = inter / (iarea + areas[j] - inter) if ovr >= thresh: suppressed[j] = 1 return keep
参考博客:http://blog.csdn.net/shuzfan/article/details/52711706
http://www.cnblogs.com/makefile/p/nms.html
阅读全文
0 0
- NMS非极大值抑制的原理与代码实现
- NMS非极大值抑制
- 非极大值抑制 NMS
- 非极大值抑制NMS
- 非极大值抑制(NMS)
- 非极大值抑制(NMS)
- NMS(非极大值抑制)
- 非极大值抑制(NMS)
- 非极大值抑制算法 NMS
- NMS非极大值抑制:用擂台赛带你从原理到代码脑洞大开恍然大悟
- 非极大值抑制原理
- NMS——非极大值抑制
- NMS——非极大值抑制
- NMS——非极大值抑制
- 非极大值抑制算法 (NMS)
- 非极大值抑制(Non-maximum suppression, NMS)
- 非极大值抑制(Non-maximum suppression, NMS)
- NMS——非极大值抑制
- Python全栈之路:Linux下的HelloWorld
- Retrofit&RxJava购物车
- HDU 2039 三角形
- Building+your+Deep+Neural+Network+-+Step+by+Step+v5 课程一第四周编程作业 1
- Android新特性介绍,ConstraintLayout完全解析(吕万友:转载)
- NMS非极大值抑制的原理与代码实现
- springmvc执行流程
- Servlet-过滤器
- python 中集成 mysql
- 【bzoj 2460】元素(线性基)
- 如何用消息系统避免分布式事务?
- iOS开发网络篇 一一 获取文件MIMEType的方式
- 使用tensorboard问题总结
- LeetCode 75. Sort Colors