paper:https://arxiv.org/pdf/1910.13302.pdf
code: https://github.com/ZFTurbo/Weighted-Boxes-Fusion

前言

我们了解NMS及其soft-NMS。但在这篇博文将简单介绍下WBF(加权框融合),该方法在开放图像数据集中取得了较大的提高。

WBF的优势

NMS和soft-NMS都排除了一些框,但是WBF利用了所有框的信息。它可以解决某些情况下,模型预测的框不准确。NMS将只能留下一个不准确的框,而WBF将使用来自3个框的信息来修复它,如下图所示,红色的为预测,蓝色的为真值。

代码

# coding: utf-8
__author__ = 'ZFTurbo: https://kaggle.com/zfturbo'import numpy as npdef bb_intersection_over_union(A, B):xA = max(A[0], B[0])yA = max(A[1], B[1])xB = min(A[2], B[2])yB = min(A[3], B[3])# compute the area of intersection rectangleinterArea = max(0, xB - xA) * max(0, yB - yA)if interArea == 0:return 0.0# compute the area of both the prediction and ground-truth rectanglesboxAArea = (A[2] - A[0]) * (A[3] - A[1])boxBArea = (B[2] - B[0]) * (B[3] - B[1])iou = interArea / float(boxAArea + boxBArea - interArea)return ioudef prefilter_boxes(boxes, scores, labels, weights, thr):# Create dict with boxes stored by its labelnew_boxes = dict()for t in range(len(boxes)):for j in range(len(boxes[t])):score = scores[t][j]if score < thr:continuelabel = int(labels[t][j])box_part = boxes[t][j]b = [int(label), float(score) * weights[t], float(box_part[0]), float(box_part[1]), float(box_part[2]), float(box_part[3])]if label not in new_boxes:new_boxes[label] = []new_boxes[label].append(b)# Sort each list in dict by score and transform it to numpy arrayfor k in new_boxes:current_boxes = np.array(new_boxes[k])new_boxes[k] = current_boxes[current_boxes[:, 1].argsort()[::-1]]return new_boxesdef get_weighted_box(boxes, conf_type='avg'):"""Create weighted box for set of boxes:param boxes: set of boxes to fuse :param conf_type: type of confidence one of 'avg' or 'max':return: weighted box"""box = np.zeros(6, dtype=np.float32)conf = 0conf_list = []for b in boxes:box[2:] += (b[1] * b[2:])conf += b[1]conf_list.append(b[1])box[0] = boxes[0][0]if conf_type == 'avg':box[1] = conf / len(boxes)elif conf_type == 'max':box[1] = np.array(conf_list).max()box[2:] /= confreturn boxdef find_matching_box(boxes_list, new_box, match_iou):best_iou = match_ioubest_index = -1for i in range(len(boxes_list)):box = boxes_list[i]if box[0] != new_box[0]:continueiou = bb_intersection_over_union(box[2:], new_box[2:])if iou > best_iou:best_index = ibest_iou = ioureturn best_index, best_ioudef weighted_boxes_fusion(boxes_list, scores_list, labels_list, weights=None, iou_thr=0.55, skip_box_thr=0.0, conf_type='avg', allows_overflow=False):''':param boxes_list: list of boxes predictions from each model, each box is 4 numbers. It has 3 dimensions (models_number, model_preds, 4)Order of boxes: x1, y1, x2, y2. We expect float normalized coordinates [0; 1]:param scores_list: list of scores for each model :param labels_list: list of labels for each model:param weights: list of weights for each model. Default: None, which means weight == 1 for each model:param iou_thr: IoU value for boxes to be a match:param skip_box_thr: exclude boxes with score lower than this variable  :param conf_type: how to calculate confidence in weighted boxes. 'avg': average value, 'max': maximum value:param allows_overflow: false if we want confidence score not exceed 1.0 :return: boxes: boxes coordinates (Order of boxes: x1, y1, x2, y2). :return: scores: confidence scores:return: labels: boxes labels'''if weights is None:weights = np.ones(len(boxes_list))if len(weights) != len(boxes_list):print('Warning: incorrect number of weights {}. Must be: {}. Set weights equal to 1.'.format(len(weights), len(boxes_list)))weights = np.ones(len(boxes_list))weights = np.array(weights)if conf_type not in ['avg', 'max']:print('Unknown conf_type: {}. Must be "avg" or "max"'.format(conf_type))exit()filtered_boxes = prefilter_boxes(boxes_list, scores_list, labels_list, weights, skip_box_thr)if len(filtered_boxes) == 0:return np.zeros((0, 4)), np.zeros((0,)), np.zeros((0,))overall_boxes = []for label in filtered_boxes:boxes = filtered_boxes[label]new_boxes = []weighted_boxes = []# Clusterize boxesfor j in range(0, len(boxes)):index, best_iou = find_matching_box(weighted_boxes, boxes[j], iou_thr)if index != -1:new_boxes[index].append(boxes[j])weighted_boxes[index] = get_weighted_box(new_boxes[index], conf_type)else:new_boxes.append([boxes[j].copy()])weighted_boxes.append(boxes[j].copy())# Rescale confidence based on number of models and boxesfor i in range(len(new_boxes)):if not allows_overflow:weighted_boxes[i][1] = weighted_boxes[i][1] * min(weights.sum(), len(new_boxes[i])) / weights.sum()else:weighted_boxes[i][1] = weighted_boxes[i][1] * len(new_boxes[i]) / weights.sum()overall_boxes.append(np.array(weighted_boxes))overall_boxes = np.concatenate(overall_boxes, axis=0)overall_boxes = overall_boxes[overall_boxes[:, 1].argsort()[::-1]]boxes = overall_boxes[:, 2:]scores = overall_boxes[:, 1]labels = overall_boxes[:, 0]return boxes, scores, labels

Weighted Boxes Fusion相关推荐

  1. 目标检测中的NMS,soft NMS,softer NMS,Weighted Boxes Fusion

    NMS 非最大值抑制算法,诞生至少50年了. 在经典的两阶段目标检测算法中,为了提高对于目标的召回率,在anchor阶段会生成密密麻麻的anchor框. 所以在后处理的时候,会存在着很多冗余框对应着同 ...

  2. CV竞赛项目研究:脊柱疾病诊断(天池,GPU赛道,2020年9月)

    目录 0 总的感受 当前阶段,竞赛还是2个关键: get点: 1 简介 1.1 需求 1.2 数据集 1.2.1 MRI数据 第6名:"我是一个搬砖工",南加州.上交大,2人. 1 ...

  3. ECCV 2020 | 首届GigaVision挑战赛揭榜,双赛道冠军技术干货分享

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要15分钟 Follow小博主,每天更新前沿干货 来源:DeepBlueAI 编辑:白峰 近日,全球计算机视觉顶会ECCV2020落下帷幕,各个 ...

  4. 【数据竞赛】AI在垃圾分类中的应用小侃(海华大赛获奖者系列分享一)

    文章来源于网络人工智能园地,作者刘迎飞 我们团队汪汪队,团队成员分别来自中科院空天信息研究院和浙江大学,有幸在biendata与海华交叉信息研究院举办的垃圾分类比赛中收获第三名的成绩,在这里简单跟大家 ...

  5. 目标检测多模型集成方法总结

    本文转载自AI公园. 前段时间推送了文章:难以置信的目标检测小妙招:多训练几个epochs,平均一下就能获得更好的模型 ,不少朋友对模型集成感兴趣,本文是个小总结. 作者:Vikas S Shetty ...

  6. ECCV 2020 GigaVision挑战赛“行人和车辆检测”和“多目标追踪”冠军方案解读

    本文转载自DeepBlue深兰科技. 日前,全球计算机视觉顶会ECCV 2020落下帷幕,各项挑战赛的结果也尘埃落定.深兰科技DeepBlueAI 团队包揽了首届GigaVision挑战赛" ...

  7. 收藏 | 目标检测的模型集成与实验

    点上方蓝字计算机视觉联盟获取更多干货 在右上方 ··· 设为星标 ★,与你不见不散 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:作者:Vikas S Shetty  |  编译:rongh ...

  8. AI大有可为:NAIE平台助力垃圾分类

    如今AI已经是这个时代智能的代名词了,任何领域都有AI的身影,垃圾分类及监管等场景自然也少不了"AI+"的赋能. 不过,垃圾往往属于商品的极端变形体,情况比较特殊.目前的技术在视觉 ...

  9. 《南溪的目标检测学习笔记》——后处理方法的学习笔记

    1 前言 后处理方法是很重要的,我在学习训练COCO数据集时深有体会,这里用笔记记录一下后处理的相关知识- 2 南溪使用的的后处理方法 南溪使用后处理操作流程: 阈值过滤(低阈值去框,提速nms)→\ ...

  10. TPH-YOLOv5简述

    引言   无人机捕获场景下的目标检测技术已广泛应用于植物保护.野生动物保护和城市监测等实际应用中,在无人机捕获的图像上的目标检测性能,并为上述众多的应用提供洞察力.本文专注于在无人机上的目标检测性能提 ...

最新文章

  1. 如何完成一次快速的查询?
  2. 计算机考研最后四十天,2021考研最后四十天冲刺复习攻略
  3. RAID2.0核心思想:数据保护与物理资源管理域分离
  4. Transformer入门篇-深度万字长文带你轻松入门深度学习框架
  5. 趣味c语言编程100例(一)
  6. 利用WinRAR命令行压缩文件或文件夹2007-11-14 15:07压缩文件夹
  7. kali-linux下搭建DVWA环境
  8. 数据结构与算法之希尔排序
  9. mysql 生明变量_在 MySQL 的 SQL 文件中,定义变量与使用变量
  10. mysql索引之二级索引学习总结
  11. PHP 常用代码大全
  12. 分分钟使用Retrofit+Rxjava实现网络请求
  13. Android 系统编译环境设置及源代码编译
  14. java基础学习(4)
  15. ARFoundation之路-人脸检测增强之一
  16. 经典算法:蒙特卡洛方法(MCMC)
  17. 和秋叶一起学PPT之段落排版与字体(课时四、五)
  18. Netapp存储 硬盘显示bad label的解决办法
  19. 全国省市区java_Jsoup获取全国地区数据(省市县镇村)
  20. STM32F7--->SDRAM

热门文章

  1. Java:轻松一刻/程序员才懂的幽默
  2. table在html是什么意思,html5中table指的是什么意思
  3. 【转】SAP 各种记账凭证的更改冲销
  4. apt cyg 安装php,Windows下安装Cygwin及apt-cyg
  5. python 根据图片后缀名判断是否为jpg
  6. 自定义ViewPager和RecyclerView指示器 Indicator
  7. 剑桥2021计算机专业,2021剑桥大学计算机专业录取条件出炉 你有信心过线吗
  8. java csrf 跨域_Django跨域请求CSRF的实例方法
  9. Python——实例1:温度转换(Python基本语法元素及框架,代码实现)
  10. 盲文压纹机和AAC设备