目标检测阅读总结(一)之RCNN以及NMS

2024-01-08 12:38

本文主要是介绍目标检测阅读总结(一)之RCNN以及NMS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

开始看目标检测方面论文,里面有很多经典,会在这儿记录下论文中的优点和代码中的问题,也会把别人blog比较好的观点总结。

阅读顺序差不多按照: https://github.com/amusi/awesome-object-detection

R-CNN

参考:https://blog.csdn.net/shenxiaolu1984/article/details/51066975

https://blog.csdn.net/briblue/article/details/82012575

 

pipeline:

1. 使用selective search生成1k-2k个候选框;

2. 对于候选区域,提取cnn特征(4096-dim),这里是裁剪出来然后做一个16的padding,然后resize到227*227。(为了让bounding box拥有上下文内容context。)

3. 对于正负样本的分类,对于4096-dim feature接一个svm进行分类。

4. 为了减少识别的错误,在用一个线性回归模型对框进行微调。

4.1. 一个scale变换,对于中心点以及长宽;

4.2 这里的L2正则化很关键;

4.3 组的pair对很重要,不然会导致a hopeless learning problem。这里使用的iou阈值为0.6。

 

3.1. 由于负样本很多,所以会对于负样本使用hard negative mining。

hard negative mining 

R-CNN引用了这篇文章 “Object Detection with Discriminatively Trained Part Based Models.”

由于训练的阶段负样本过多,超过1w个,对于模型来说使用全部的负样本是不可行的,所以需要构建一个既有负样本又有hard negative的样本集合。

Bootstrapping methods:先用负样本组成集合训练,然后收集那些被错误分类的例子,去训练新的模型,这样重复几次。

proposed data-mining methods:为了找到一个属于训练集的小子集,初始的时候用原始的作为一个cache,每一次迭代会移除一些比较简单的样本,增加一些新的比较难的样本。

具体流程如下

1. 先初始一个$C_{t}$ \subseteq $D$, 这里的 D是原来的训练集。

2. 训练,直到参数稳定分出两个集合,一个是错误分类的,一个是正确分类的。

3. 缩小C_{t}, 去除那些被正确分类的,得到集合C_{t^{'}}

4. 增大C_{t+1},把 C_{t^{'}}和一些属于 D的样本形成并集,得到新一轮的子集C_{t+1}

Non-Maximum-Suppression

非极大值抑制,在目标检测,回归了很多bounding boxes出来之后,要最终确定哪一个是最终使用的时候,需要用nms进行bounding boxes的剔除。

具体过程:对于图片每一个类别,先找到置信度(网络predict的概率)最大的值,先对于这一类别的其他框做iou的操作,然后有一个nms的iou超参,高于设定iou的就被剔除。

如此对于每一个类别进行重复操作,这样排除了很多置信度低的框。

下面贴一下自己写的nms代码,并简单分析一下。

#include <iostream>
#include <string>
#include <set>
#include <cmath>
#include <vector>
#include <tuple>
using namespace std;
float iou_cal(vector<float> box1, vector<float> box2){float right_x = min(box1[2],box2[2]);float right_y = min(box1[3],box2[3]);float left_x = max(box1[2],box2[2]);float left_y = max(box1[3],box2[3]);float overlap = fmax(0.,left_x-right_x) * fmax(0.,left_y-right_y);float area_sum = (box1[2]-box1[0])*(box1[3]-box1[1])+(box2[2]-box2[0])*(box2[3]-box2[1]);return overlap/(area_sum-overlap);
}
tuple<vector<float>,int> find_base(vector<vector<float> > boxes){vector<float> boxes_max{-1,-1,-1,-1};float max_pb = 0.;int index;for(int i = 0; i<boxes.size();i++){if(boxes[i][0]>max_pb){max_pb = boxes[i][0];boxes_max[0] = boxes[i][1];boxes_max[1] = boxes[i][2];boxes_max[2] = boxes[i][3];boxes_max[3] = boxes[i][4];index = i;}}return make_tuple(boxes_max,index);}
void nms(vector<vector<float> > &boxes,float iou_value){ // single classtuple<vector<float>,int> box_value;vector<float> boxes_base;float iou = 0.0;int index;box_value = find_base(boxes);boxes_base = get<0>(box_value);index = get<1>(box_value);for(int i=0;i<boxes.size();i++){if(i!=index){iou = iou_cal(boxes_base,boxes[i]);if(iou>iou_value){boxes.erase(boxes.begin()+i);}}}
}
void print_boxes(vector<vector<float> > boxes){for(int i=0;i<boxes.size();i++){for(int j=0;j<boxes[0].size();j++){cout << boxes[i][j] << " " ;}cout << endl;}
}int main(int argc, const char * argv[]) {vector<float> box1{0.6,100,98,300,400};vector<float> box2{0.7,85,60,250,500};vector<float> box3{0.8,70,49,200,350};vector<vector<float> > boxes;boxes.push_back(box1);boxes.push_back(box2);boxes.push_back(box3);print_boxes(boxes);nms(boxes,0.5);print_boxes(boxes);return 0;
}

上面代码考虑单一类别的情况,多类别加一个for循环即可,首先是要找到置信度最大的候选框,通过find_base函数。之后进行for循环,对于其他候选框进行判断,计算iou占比,如果小于设定的阈值(这里设定的为0.5)那么就剔除这个框。

tip:c++语法要注意nms的输入应为引用。

这篇关于目标检测阅读总结(一)之RCNN以及NMS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/583486

相关文章

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

MySQL基本查询示例总结

《MySQL基本查询示例总结》:本文主要介绍MySQL基本查询示例总结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Create插入替换Retrieve(读取)select(确定列)where条件(确定行)null查询order by语句li

Linux区分SSD和机械硬盘的方法总结

《Linux区分SSD和机械硬盘的方法总结》在Linux系统管理中,了解存储设备的类型和特性是至关重要的,不同的存储介质(如固态硬盘SSD和机械硬盘HDD)在性能、可靠性和适用场景上有着显著差异,本文... 目录一、lsblk 命令简介基本用法二、识别磁盘类型的关键参数:ROTA查询 ROTA 参数ROTA

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义