目标检测阅读总结(一)之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

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

(超详细)YOLOV7改进-Soft-NMS(支持多种IoU变种选择)

1.在until/general.py文件最后加上下面代码 2.在general.py里面找到这代码,修改这两个地方 3.之后直接运行即可

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

Java注解详细总结

什么是注解?         Java注解是代码中的特殊标记,比如@Override、@Test等,作用是:让其他程序根据注解信息决定怎么执行该程序。         注解不光可以用在方法上,还可以用在类上、变量上、构造器上等位置。 自定义注解  现在我们自定义一个MyTest注解 public @interface MyTest{String aaa();boolean bbb()

tensorboard-----summary用法总结

Tensorflow学习笔记——Summary用法         最近在研究tensorflow自带的例程speech_command,顺便学习tensorflow的一些基本用法。 其中tensorboard 作为一款可视化神器,可以说是学习tensorflow时模型训练以及参数可视化的法宝。 而在训练过程中,主要用到了tf.summary()的各类方法,能够保存训练过程以及参数分布图并在

基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别

转发来源:https://swift.ctolib.com/ooooverflow-chinese-ocr.html chinese-ocr 基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别 环境部署 sh setup.sh 使用环境: python 3.6 + tensorflow 1.10 +pytorch 0.4.1 注:CPU环境

3月份目标——刷完乙级真题

https://www.patest.cn/contests/pat-b-practisePAT (Basic Level) Practice (中文) 标号标题通过提交通过率1001害死人不偿命的(3n+1)猜想 (15)31858792260.41002写出这个数 (20)21702664840.331003我要通过!(20)11071447060.251004成绩排名 (20)159644

七种排序方式总结

/*2018.01.23*A:YUAN*T:其中排序算法:冒泡排序,简单排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序*/#include <stdio.h>#include <math.h>#include <malloc.h>#define MAXSIZE 10000#define FALSE 0#define TRUE 1typedef struct {i

Java实现MD5加密总结

Java实现MD5加密总结 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 什么是MD5加密 MD5是一种常用的哈希算法,用于将任意长度的数据通过哈希运算转换为固定长度的数据串,通常为128位的二进制串,常用于对密码等敏感信息进行加密存储或传输。 2. Java实现MD5加密的方法 2.1 使用java.sec