Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleDetection
提交
486121ea
P
PaddleDetection
项目概览
PaddlePaddle
/
PaddleDetection
大约 1 年 前同步成功
通知
695
Star
11112
Fork
2696
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
184
列表
看板
标记
里程碑
合并请求
40
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleDetection
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
184
Issue
184
列表
看板
标记
里程碑
合并请求
40
合并请求
40
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
486121ea
编写于
8月 24, 2022
作者:
F
Feng Ni
提交者:
GitHub
8月 24, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[smalldet] fix slice_infer (#6744)
* fix slice_infer * fix doc, test=document_fix
上级
6cad94fc
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
222 addition
and
159 deletion
+222
-159
configs/smalldet/README.md
configs/smalldet/README.md
+143
-119
deploy/python/infer.py
deploy/python/infer.py
+45
-8
deploy/python/utils.py
deploy/python/utils.py
+1
-1
ppdet/engine/trainer.py
ppdet/engine/trainer.py
+31
-29
tools/eval.py
tools/eval.py
+1
-1
tools/infer.py
tools/infer.py
+1
-1
未找到文件。
configs/smalldet/README.md
浏览文件 @
486121ea
# PP-YOLOE 小目标检测模型
# PP-YOLOE 小目标检测模型(PP-YOLOE smalldet)
PaddleDetection团队提供了针对VisDrone-DET、DOTA水平框、Xview等小目标场景数据集的基于PP-YOLOE的检测模型,以及提供了一套使用
[
SAHI
](
https://github.com/obss/sahi
)(
Slicing
Aided Hyper Inference)工具切图和拼图的方案,用户可以下载模型进行使用。
<img
src=
"https://user-images.githubusercontent.com/82303451/182520025-f6bd1c76-a9f9-4f8c-af9b-b37a403258d8.png"
title=
"VisDrone"
alt=
"VisDrone"
width=
"300"
><img
src=
"https://user-images.githubusercontent.com/82303451/182521833-4aa0314c-b3f2-4711-9a65-cabece612737.png"
title=
"VisDrone"
alt=
"VisDrone"
width=
"300"
><img
src=
"https://user-images.githubusercontent.com/82303451/182520038-cacd5d09-0b85-475c-8e59-72f1fc48eef8.png"
title=
"DOTA"
alt=
"DOTA"
height=
"168"
><img
src=
"https://user-images.githubusercontent.com/82303451/182524123-dcba55a2-ce2d-4ba1-9d5b-eb99cb440715.jpeg"
title=
"Xview"
alt=
"Xview"
height=
"168"
>
<img
src=
"https://user-images.githubusercontent.com/82303451/182520025-f6bd1c76-a9f9-4f8c-af9b-b37a403258d8.png"
title=
"VisDrone"
alt=
"VisDrone"
width=
"300"
><img
src=
"https://user-images.githubusercontent.com/82303451/182521833-4aa0314c-b3f2-4711-9a65-cabece612737.png"
title=
"VisDrone"
alt=
"VisDrone"
width=
"300"
><img
src=
"https://user-images.githubusercontent.com/82303451/182520038-cacd5d09-0b85-475c-8e59-72f1fc48eef8.png"
title=
"DOTA"
alt=
"DOTA"
height=
"168"
><img
src=
"https://user-images.githubusercontent.com/82303451/182524123-dcba55a2-ce2d-4ba1-9d5b-eb99cb440715.jpeg"
title=
"Xview"
alt=
"Xview"
height=
"168"
>
## 基础模型:
## 内容
-
[
简介
](
#简介
)
-
[
模型库
](
#模型库
)
-
[
基础模型
](
#基础模型
)
-
[
拼图模型
](
#拼图模型
)
-
[
数据集准备
](
#数据集准备
)
-
[
模型库使用说明
](
#模型库使用说明
)
-
[
训练
](
#训练
)
-
[
评估
](
#评估
)
-
[
预测
](
#预测
)
-
[
部署
](
#部署
)
-
[
切图使用说明
](
#切图使用说明
)
-
[
统计数据集分布
](
#统计数据集分布
)
-
[
SAHI切图
](
#SAHI切图
)
-
[
引用
](
#引用
)
## 简介
PaddleDetection团队提供了针对VisDrone-DET、DOTA水平框、Xview等小目标场景数据集的基于PP-YOLOE的检测模型,以及提供了一套使用
[
SAHI
](
https://github.com/obss/sahi
)(
Slicing
Aided Hyper Inference)工具切图和拼图的方案,用户可以下载模型进行使用。不通过切图拼图而直接使用原图的方案也可以参照
[
visdrone
](
../visdrone
)
。
**是否需要切图**
,建议参照
[
切图使用说明
](
#切图使用说明
)
中的
[
统计数据集分布
](
#统计数据集分布
)
先分析一下数据集再确定。
## 模型库
### 基础模型
| 模型 | 数据集 | SLICE_SIZE | OVERLAP_RATIO | 类别数 | mAP
<sup>
val
<br>
0.5:0.95 | AP
<sup>
val
<br>
0.5 | 下载链接 | 配置文件 |
| 模型 | 数据集 | SLICE_SIZE | OVERLAP_RATIO | 类别数 | mAP
<sup>
val
<br>
0.5:0.95 | AP
<sup>
val
<br>
0.5 | 下载链接 | 配置文件 |
|:---------|:---------------:|:---------------:|:---------------:|:------:|:-----------------------:|:-------------------:|:---------:| :-----: |
|:---------|:---------------:|:---------------:|:---------------:|:------:|:-----------------------:|:-------------------:|:---------:| :-----: |
...
@@ -12,7 +31,7 @@ PaddleDetection团队提供了针对VisDrone-DET、DOTA水平框、Xview等小
...
@@ -12,7 +31,7 @@ PaddleDetection团队提供了针对VisDrone-DET、DOTA水平框、Xview等小
|PP-YOLOE-P2-l| Xview | 400 | 0.25 | 60 | 14.9 | 27.0 |
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/models/ppyoloe_p2_crn_l_80e_sliced_xview_400_025.pdparams
)
|
[
配置文件
](
./ppyoloe_p2_crn_l_80e_sliced_xview_400_025.yml
)
|
|PP-YOLOE-P2-l| Xview | 400 | 0.25 | 60 | 14.9 | 27.0 |
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/models/ppyoloe_p2_crn_l_80e_sliced_xview_400_025.pdparams
)
|
[
配置文件
](
./ppyoloe_p2_crn_l_80e_sliced_xview_400_025.yml
)
|
|PP-YOLOE-l| VisDrone-DET| 640 | 0.25 | 10 | 38.5 | 60.2 |
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
)
|
[
配置文件
](
./ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
)
|
|PP-YOLOE-l| VisDrone-DET| 640 | 0.25 | 10 | 38.5 | 60.2 |
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
)
|
[
配置文件
](
./ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
)
|
##
原图评估和拼图评估对比:
##
# 拼图模型
| 模型 | 数据集 | SLICE_SIZE | OVERLAP_RATIO | 类别数 | mAP
<sup>
val
<br>
0.5:0.95 | AP
<sup>
val
<br>
0.5 | 下载链接 | 配置文件 |
| 模型 | 数据集 | SLICE_SIZE | OVERLAP_RATIO | 类别数 | mAP
<sup>
val
<br>
0.5:0.95 | AP
<sup>
val
<br>
0.5 | 下载链接 | 配置文件 |
|:---------|:---------------:|:---------------:|:---------------:|:------:|:-----------------------:|:-------------------:|:---------:| :-----: |
|:---------|:---------------:|:---------------:|:---------------:|:------:|:-----------------------:|:-------------------:|:---------:| :-----: |
...
@@ -28,10 +47,100 @@ PaddleDetection团队提供了针对VisDrone-DET、DOTA水平框、Xview等小
...
@@ -28,10 +47,100 @@ PaddleDetection团队提供了针对VisDrone-DET、DOTA水平框、Xview等小
-
自动切图和拼图的推理预测需添加设置
`--slice_infer`
,具体见下文使用说明。
-
自动切图和拼图的推理预测需添加设置
`--slice_infer`
,具体见下文使用说明。
-
Assembled表示自动切图和拼图。
-
Assembled表示自动切图和拼图。
## 数据集准备
### VisDrone-DET
VisDrone-DET是一个无人机航拍场景的小目标数据集,整理后的COCO格式VisDrone-DET数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/visdrone.zip
)
,切图后的COCO格式数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/visdrone_sliced.zip
)
,检测其中的
**10类**
,包括
`pedestrian(1), people(2), bicycle(3), car(4), van(5), truck(6), tricycle(7), awning-tricycle(8), bus(9), motor(10)`
,原始数据集
[
下载链接
](
https://github.com/VisDrone/VisDrone-Dataset
)
。
具体使用和下载请参考
[
visdrone
](
../visdrone
)
。
### DOTA水平框
DOTA是一个大型的遥感影像公开数据集,这里使用
**DOTA-v1.0**
水平框数据集,切图后整理的COCO格式的DOTA水平框数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/dota_sliced.zip
)
,检测其中的
**15类**
,
包括
`plane(0), baseball-diamond(1), bridge(2), ground-track-field(3), small-vehicle(4), large-vehicle(5), ship(6), tennis-court(7),basketball-court(8), storage-tank(9), soccer-ball-field(10), roundabout(11), harbor(12), swimming-pool(13), helicopter(14)`
,
图片及原始数据集
[
下载链接
](
https://captain-whu.github.io/DOAI2019/dataset.html
)
。
### Xview
Xview是一个大型的航拍遥感检测数据集,目标极小极多,切图后整理的COCO格式数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/xview_sliced.zip
)
,检测其中的
**60类**
,
具体类别为:
<details>
`Fixed-wing Aircraft(0),
Small Aircraft(1),
Cargo Plane(2),
Helicopter(3),
Passenger Vehicle(4),
Small Car(5),
Bus(6),
Pickup Truck(7),
Utility Truck(8),
Truck(9),
Cargo Truck(10),
Truck w/Box(11),
Truck Tractor(12),
Trailer(13),
Truck w/Flatbed(14),
Truck w/Liquid(15),
Crane Truck(16),
Railway Vehicle(17),
Passenger Car(18),
Cargo Car(19),
Flat Car(20),
Tank car(21),
Locomotive(22),
Maritime Vessel(23),
Motorboat(24),
Sailboat(25),
Tugboat(26),
Barge(27),
Fishing Vessel(28),
Ferry(29),
Yacht(30),
Container Ship(31),
Oil Tanker(32),
Engineering Vehicle(33),
Tower crane(34),
Container Crane(35),
Reach Stacker(36),
Straddle Carrier(37),
Mobile Crane(38),
Dump Truck(39),
Haul Truck(40),
Scraper/Tractor(41),
Front loader/Bulldozer(42),
Excavator(43),
Cement Mixer(44),
Ground Grader(45),
Hut/Tent(46),
Shed(47),
Building(48),
Aircraft Hangar(49),
Damaged Building(50),
Facility(51),
Construction Site(52),
Vehicle Lot(53),
Helipad(54),
Storage Tank(55),
Shipping container lot(56),
Shipping Container(57),
Pylon(58),
Tower(59)
`
</details>
,原始数据集
[
下载链接
](
https://challenge.xviewdataset.org/download-links
)
。
#
使用说明
#
## 用户自定义数据集准备
## 1.训练
用户自定义数据集准备请参考
[
DET数据集标注工具
](
../../docs/tutorials/data/DetAnnoTools.md
)
和
[
DET数据集准备教程
](
../../docs/tutorials/data/PrepareDetDataSet.md
)
去准备。
## 模型库使用说明
### 训练
首先将你的数据集为COCO数据集格式,然后使用SAHI切图工具进行离线切图,对保存的子图按常规检测模型的训练流程走即可。
首先将你的数据集为COCO数据集格式,然后使用SAHI切图工具进行离线切图,对保存的子图按常规检测模型的训练流程走即可。
也可直接下载PaddleDetection团队提供的切图后的VisDrone-DET、DOTA水平框、Xview数据集。
也可直接下载PaddleDetection团队提供的切图后的VisDrone-DET、DOTA水平框、Xview数据集。
...
@@ -45,9 +154,9 @@ python -m paddle.distributed.launch --gpus 0,1,2,3,4,5,6,7 tools/train.py -c con
...
@@ -45,9 +154,9 @@ python -m paddle.distributed.launch --gpus 0,1,2,3,4,5,6,7 tools/train.py -c con
**注意:**
**注意:**
-
使用默认配置训练需要设置
`--amp`
以避免显存溢出。
-
使用默认配置训练需要设置
`--amp`
以避免显存溢出。
##
2.
评估
##
#
评估
###
2.1 子图评估:
###
# 2.1 子图评估
默认评估方式是子图评估,子图数据集的验证集设置为:
默认评估方式是子图评估,子图数据集的验证集设置为:
```
```
...
@@ -62,7 +171,7 @@ EvalDataset:
...
@@ -62,7 +171,7 @@ EvalDataset:
CUDA_VISIBLE_DEVICES
=
0 python tools/eval.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
CUDA_VISIBLE_DEVICES
=
0 python tools/eval.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
```
```
###
2.2 原图评估:
###
# 2.2 原图评估
修改验证集的标注文件路径为原图标注文件:
修改验证集的标注文件路径为原图标注文件:
```
```
EvalDataset:
EvalDataset:
...
@@ -76,7 +185,7 @@ EvalDataset:
...
@@ -76,7 +185,7 @@ EvalDataset:
CUDA_VISIBLE_DEVICES
=
0 python tools/eval.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
CUDA_VISIBLE_DEVICES
=
0 python tools/eval.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
```
```
###
2.3 子图拼图评估:
###
# 2.3 子图拼图评估
修改验证集的标注文件路径为原图标注文件:
修改验证集的标注文件路径为原图标注文件:
```
```
# very slow, preferly eval with a determined weights(xx.pdparams)
# very slow, preferly eval with a determined weights(xx.pdparams)
...
@@ -94,17 +203,9 @@ EvalDataset:
...
@@ -94,17 +203,9 @@ EvalDataset:
CUDA_VISIBLE_DEVICES
=
0 python tools/eval.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025_slice_infer.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
--slice_infer
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
CUDA_VISIBLE_DEVICES
=
0 python tools/eval.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025_slice_infer.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
--slice_infer
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
```
```
-
设置
`--slice_infer`
表示切图预测并拼装重组结果,如果不使用则不写;
-
设置
`--slice_size`
表示切图的子图尺寸大小,设置
`--overlap_ratio`
表示子图间重叠率;
-
设置
`--combine_method`
表示子图结果重组去重的方式,默认是
`nms`
;
-
设置
`--match_threshold`
表示子图结果重组去重的阈值,默认是0.6;
-
设置
`--match_metric`
表示子图结果重组去重的度量标准,默认是
`ios`
表示交小比(两个框交集面积除以更小框的面积),也可以选择交并比
`iou`
(两个框交集面积除以并集面积),精度效果因数据集而而异,但选择
`ios`
预测速度会更快一点;
**注意:**
**注意:**
-
设置
`--slice_infer`
表示切图预测并拼装重组结果,如果不使用则不写,注意需要确保EvalDataset的数据集类是选用的SlicedCOCODataSet而不是COCODataSet;
-
设置
`--slice_infer`
表示切图预测并拼装重组结果,如果不使用则不写,注意需要确保EvalDataset的数据集类是选用的SlicedCOCODataSet而不是COCODataSet;
-
可以自行修改选择合适的子图尺度sliced_size和子图间重叠率overlap_ratio,如:
-
设置
`--slice_size`
表示切图的子图尺寸大小,设置
`--overlap_ratio`
表示子图间重叠率,
可以自行修改选择合适的子图尺度sliced_size和子图间重叠率overlap_ratio,如:
```
```
EvalDataset:
EvalDataset:
!SlicedCOCODataSet
!SlicedCOCODataSet
...
@@ -119,18 +220,21 @@ EvalDataset:
...
@@ -119,18 +220,21 @@ EvalDataset:
-
设置
`--match_metric`
表示子图结果重组去重的度量标准,默认是
`ios`
表示交小比(两个框交集面积除以更小框的面积),也可以选择交并比
`iou`
(两个框交集面积除以并集面积),精度效果因数据集而而异,但选择
`ios`
预测速度会更快一点;
-
设置
`--match_metric`
表示子图结果重组去重的度量标准,默认是
`ios`
表示交小比(两个框交集面积除以更小框的面积),也可以选择交并比
`iou`
(两个框交集面积除以并集面积),精度效果因数据集而而异,但选择
`ios`
预测速度会更快一点;
##
3.
预测
##
#
预测
###
3.1 子图或原图直接预测:
###
# 3.1 子图或原图直接预测
与评估流程基本相同,可以在提前切好并存下来的子图上预测,也可以对原图预测,如:
与评估流程基本相同,可以在提前切好并存下来的子图上预测,也可以对原图预测,如:
```
bash
```
bash
CUDA_VISIBLE_DEVICES
=
0 python tools/infer.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
--infer_img
=
demo.jpg
--draw_threshold
=
0.25
CUDA_VISIBLE_DEVICES
=
0 python tools/infer.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
--infer_img
=
demo.jpg
--draw_threshold
=
0.25
```
```
###
3.2 原图自动切图并拼图预测:
###
# 3.2 原图自动切图并拼图预测
也可以对原图进行自动切图并拼图重组来预测原图,如:
也可以对原图进行自动切图并拼图重组来预测原图,如:
```
bash
```
bash
# 单张图
CUDA_VISIBLE_DEVICES
=
0 python tools/infer.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
--infer_img
=
demo.jpg
--draw_threshold
=
0.25
--slice_infer
--slice_size
640 640
--overlap_ratio
0.25 0.25
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
CUDA_VISIBLE_DEVICES
=
0 python tools/infer.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
--infer_img
=
demo.jpg
--draw_threshold
=
0.25
--slice_infer
--slice_size
640 640
--overlap_ratio
0.25 0.25
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
# 或图片文件夹
CUDA_VISIBLE_DEVICES
=
0 python tools/infer.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
--infer_dir
=
demo/
--draw_threshold
=
0.25
--slice_infer
--slice_size
640 640
--overlap_ratio
0.25 0.25
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
```
```
-
设置
`--slice_infer`
表示切图预测并拼装重组结果,如果不使用则不写;
-
设置
`--slice_infer`
表示切图预测并拼装重组结果,如果不使用则不写;
-
设置
`--slice_size`
表示切图的子图尺寸大小,设置
`--overlap_ratio`
表示子图间重叠率;
-
设置
`--slice_size`
表示切图的子图尺寸大小,设置
`--overlap_ratio`
表示子图间重叠率;
...
@@ -139,24 +243,27 @@ CUDA_VISIBLE_DEVICES=0 python tools/infer.py -c configs/smalldet/ppyoloe_crn_l_8
...
@@ -139,24 +243,27 @@ CUDA_VISIBLE_DEVICES=0 python tools/infer.py -c configs/smalldet/ppyoloe_crn_l_8
-
设置
`--match_metric`
表示子图结果重组去重的度量标准,默认是
`ios`
表示交小比(两个框交集面积除以更小框的面积),也可以选择交并比
`iou`
(两个框交集面积除以并集面积),精度效果因数据集而而异,但选择
`ios`
预测速度会更快一点;
-
设置
`--match_metric`
表示子图结果重组去重的度量标准,默认是
`ios`
表示交小比(两个框交集面积除以更小框的面积),也可以选择交并比
`iou`
(两个框交集面积除以并集面积),精度效果因数据集而而异,但选择
`ios`
预测速度会更快一点;
##
4.
部署
##
#
部署
### 4.1 导出模型
###
#
4.1 导出模型
```
bash
```
bash
# export model
# export model
CUDA_VISIBLE_DEVICES
=
0 python tools/export_model.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
CUDA_VISIBLE_DEVICES
=
0 python tools/export_model.py
-c
configs/smalldet/ppyoloe_crn_l_80e_sliced_visdrone_640_025.yml
-o
weights
=
https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_80e_sliced_visdrone_640_025.pdparams
```
```
###
4.2 使用原图或子图直接推理:
###
# 4.2 使用原图或子图直接推理
```
bash
```
bash
# deploy infer
# deploy infer
CUDA_VISIBLE_DEVICES
=
0 python deploy/python/infer.py
--model_dir
=
output_inference/ppyoloe_crn_l_80e_sliced_visdrone_640_025
--image_file
=
demo.jpg
--device
=
GPU
--threshold
=
0.25
CUDA_VISIBLE_DEVICES
=
0 python deploy/python/infer.py
--model_dir
=
output_inference/ppyoloe_crn_l_80e_sliced_visdrone_640_025
--image_file
=
demo.jpg
--device
=
GPU
--
save_images
--
threshold
=
0.25
```
```
###
4.3 使用原图自动切图并拼图重组结果来推理:
###
# 4.3 使用原图自动切图并拼图重组结果来推理
```
bash
```
bash
# deploy slice infer
# deploy slice infer
CUDA_VISIBLE_DEVICES
=
0 python deploy/python/infer.py
--model_dir
=
output_inference/ppyoloe_crn_l_80e_sliced_visdrone_640_025
--image_file
=
demo.jpg
--device
=
GPU
--threshold
=
0.25
--slice_infer
--slice_size
640 640
--overlap_ratio
0.25 0.25
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
# 单张图
CUDA_VISIBLE_DEVICES
=
0 python deploy/python/infer.py
--model_dir
=
output_inference/ppyoloe_crn_l_80e_sliced_visdrone_640_025
--image_file
=
demo.jpg
--device
=
GPU
--save_images
--threshold
=
0.25
--slice_infer
--slice_size
640 640
--overlap_ratio
0.25 0.25
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
# 或图片文件夹
CUDA_VISIBLE_DEVICES
=
0 python deploy/python/infer.py
--model_dir
=
output_inference/ppyoloe_crn_l_80e_sliced_visdrone_640_025
--image_dir
=
demo/
--device
=
GPU
--save_images
--threshold
=
0.25
--slice_infer
--slice_size
640 640
--overlap_ratio
0.25 0.25
--combine_method
=
nms
--match_threshold
=
0.6
--match_metric
=
ios
```
```
-
设置
`--slice_infer`
表示切图预测并拼装重组结果,如果不使用则不写;
-
设置
`--slice_infer`
表示切图预测并拼装重组结果,如果不使用则不写;
-
设置
`--slice_size`
表示切图的子图尺寸大小,设置
`--overlap_ratio`
表示子图间重叠率;
-
设置
`--slice_size`
表示切图的子图尺寸大小,设置
`--overlap_ratio`
表示子图间重叠率;
...
@@ -165,94 +272,10 @@ CUDA_VISIBLE_DEVICES=0 python deploy/python/infer.py --model_dir=output_inferenc
...
@@ -165,94 +272,10 @@ CUDA_VISIBLE_DEVICES=0 python deploy/python/infer.py --model_dir=output_inferenc
-
设置
`--match_metric`
表示子图结果重组去重的度量标准,默认是
`ios`
表示交小比(两个框交集面积除以更小框的面积),也可以选择交并比
`iou`
(两个框交集面积除以并集面积),精度效果因数据集而而异,但选择
`ios`
预测速度会更快一点;
-
设置
`--match_metric`
表示子图结果重组去重的度量标准,默认是
`ios`
表示交小比(两个框交集面积除以更小框的面积),也可以选择交并比
`iou`
(两个框交集面积除以并集面积),精度效果因数据集而而异,但选择
`ios`
预测速度会更快一点;
# SAHI切图工具使用说明
## 1. 数据集下载
### VisDrone-DET
VisDrone-DET是一个无人机航拍场景的小目标数据集,整理后的COCO格式VisDrone-DET数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/visdrone.zip
)
,切图后的COCO格式数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/visdrone_sliced.zip
)
,检测其中的
**10类**
,包括
`pedestrian(1), people(2), bicycle(3), car(4), van(5), truck(6), tricycle(7), awning-tricycle(8), bus(9), motor(10)`
,原始数据集
[
下载链接
](
https://github.com/VisDrone/VisDrone-Dataset
)
。
具体使用和下载请参考
[
visdrone
](
../visdrone
)
。
### DOTA水平框:
DOTA是一个大型的遥感影像公开数据集,这里使用
**DOTA-v1.0**
水平框数据集,切图后整理的COCO格式的DOTA水平框数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/dota_sliced.zip
)
,检测其中的
**15类**
,
包括
`plane(0), baseball-diamond(1), bridge(2), ground-track-field(3), small-vehicle(4), large-vehicle(5), ship(6), tennis-court(7),basketball-court(8), storage-tank(9), soccer-ball-field(10), roundabout(11), harbor(12), swimming-pool(13), helicopter(14)`
,
图片及原始数据集
[
下载链接
](
https://captain-whu.github.io/DOAI2019/dataset.html
)
。
### Xview:
Xview是一个大型的航拍遥感检测数据集,目标极小极多,切图后整理的COCO格式数据集
[
下载链接
](
https://bj.bcebos.com/v1/paddledet/data/smalldet/xview_sliced.zip
)
,检测其中的
**60类**
,
具体类别为:
<details>
`Fixed-wing Aircraft(0),
Small Aircraft(1),
Cargo Plane(2),
Helicopter(3),
Passenger Vehicle(4),
Small Car(5),
Bus(6),
Pickup Truck(7),
Utility Truck(8),
Truck(9),
Cargo Truck(10),
Truck w/Box(11),
Truck Tractor(12),
Trailer(13),
Truck w/Flatbed(14),
Truck w/Liquid(15),
Crane Truck(16),
Railway Vehicle(17),
Passenger Car(18),
Cargo Car(19),
Flat Car(20),
Tank car(21),
Locomotive(22),
Maritime Vessel(23),
Motorboat(24),
Sailboat(25),
Tugboat(26),
Barge(27),
Fishing Vessel(28),
Ferry(29),
Yacht(30),
Container Ship(31),
Oil Tanker(32),
Engineering Vehicle(33),
Tower crane(34),
Container Crane(35),
Reach Stacker(36),
Straddle Carrier(37),
Mobile Crane(38),
Dump Truck(39),
Haul Truck(40),
Scraper/Tractor(41),
Front loader/Bulldozer(42),
Excavator(43),
Cement Mixer(44),
Ground Grader(45),
Hut/Tent(46),
Shed(47),
Building(48),
Aircraft Hangar(49),
Damaged Building(50),
Facility(51),
Construction Site(52),
Vehicle Lot(53),
Helipad(54),
Storage Tank(55),
Shipping container lot(56),
Shipping Container(57),
Pylon(58),
Tower(59)
`
</details>
## 切图使用说明
,原始数据集
[
下载链接
](
https://challenge.xviewdataset.org/download-links
)
。
##
2.
统计数据集分布
##
#
统计数据集分布
首先统计所用数据集标注框的平均宽高占图片真实宽高的比例分布:
首先统计所用数据集标注框的平均宽高占图片真实宽高的比例分布:
...
@@ -275,11 +298,11 @@ Distribution saved as box_distribution.jpg
...
@@ -275,11 +298,11 @@ Distribution saved as box_distribution.jpg
-
当原始数据集全部有标注框的图片中,
**有1/2以上的图片标注框的平均宽高与原图宽高比例小于0.04时**
,建议进行切图训练。
-
当原始数据集全部有标注框的图片中,
**有1/2以上的图片标注框的平均宽高与原图宽高比例小于0.04时**
,建议进行切图训练。
##
3.
SAHI切图
##
#
SAHI切图
针对需要切图的数据集,使用
[
SAHI
](
https://github.com/obss/sahi
)
库进行切分:
针对需要切图的数据集,使用
[
SAHI
](
https://github.com/obss/sahi
)
库进行切分:
### 安装SAHI库:
###
#
安装SAHI库:
参考
[
SAHI installation
](
https://github.com/obss/sahi/blob/main/README.md#installation
)
进行安装
参考
[
SAHI installation
](
https://github.com/obss/sahi/blob/main/README.md#installation
)
进行安装
...
@@ -287,7 +310,7 @@ Distribution saved as box_distribution.jpg
...
@@ -287,7 +310,7 @@ Distribution saved as box_distribution.jpg
pip
install
sahi
pip
install
sahi
```
```
###
基于SAHI切图:
###
# 基于SAHI切图
```
bash
```
bash
python slice_tools/slice_image.py
--image_dir
../../dataset/DOTA/train/
--json_path
../../dataset/DOTA/annotations/train.json
--output_dir
../../dataset/dota_sliced
--slice_size
500
--overlap_ratio
0.25
python slice_tools/slice_image.py
--image_dir
../../dataset/DOTA/train/
--json_path
../../dataset/DOTA/annotations/train.json
--output_dir
../../dataset/dota_sliced
--slice_size
500
--overlap_ratio
0.25
...
@@ -301,7 +324,8 @@ python slice_tools/slice_image.py --image_dir ../../dataset/DOTA/train/ --json_p
...
@@ -301,7 +324,8 @@ python slice_tools/slice_image.py --image_dir ../../dataset/DOTA/train/ --json_p
-
以上述代码为例,切分后的子图文件夹与json标注文件共同保存在
`dota_sliced`
文件夹下,分别命名为
`train_images_500_025`
、
`train_500_025.json`
。
-
以上述代码为例,切分后的子图文件夹与json标注文件共同保存在
`dota_sliced`
文件夹下,分别命名为
`train_images_500_025`
、
`train_500_025.json`
。
# 引用
## 引用
```
```
@article{akyon2022sahi,
@article{akyon2022sahi,
title={Slicing Aided Hyper Inference and Fine-tuning for Small Object Detection},
title={Slicing Aided Hyper Inference and Fine-tuning for Small Object Detection},
...
...
deploy/python/infer.py
浏览文件 @
486121ea
...
@@ -224,7 +224,9 @@ class Detector(object):
...
@@ -224,7 +224,9 @@ class Detector(object):
overlap_ratio
=
[
0.25
,
0.25
],
overlap_ratio
=
[
0.25
,
0.25
],
combine_method
=
'nms'
,
combine_method
=
'nms'
,
match_threshold
=
0.6
,
match_threshold
=
0.6
,
match_metric
=
'iou'
,
match_metric
=
'ios'
,
run_benchmark
=
False
,
repeats
=
1
,
visual
=
True
,
visual
=
True
,
save_results
=
False
):
save_results
=
False
):
# slice infer only support bs=1
# slice infer only support bs=1
...
@@ -249,10 +251,38 @@ class Detector(object):
...
@@ -249,10 +251,38 @@ class Detector(object):
overlap_width_ratio
=
overlap_ratio
[
1
])
overlap_width_ratio
=
overlap_ratio
[
1
])
sub_img_num
=
len
(
slice_image_result
)
sub_img_num
=
len
(
slice_image_result
)
merged_bboxs
=
[]
merged_bboxs
=
[]
for
_ind
in
range
(
sub_img_num
):
im
=
slice_image_result
.
images
[
_ind
]
batch_image_list
=
[
slice_image_result
.
images
[
_ind
]
for
_ind
in
range
(
sub_img_num
)
]
if
run_benchmark
:
# preprocess
inputs
=
self
.
preprocess
(
batch_image_list
)
# warmup
self
.
det_times
.
preprocess_time_s
.
start
()
inputs
=
self
.
preprocess
(
batch_image_list
)
self
.
det_times
.
preprocess_time_s
.
end
()
# model prediction
result
=
self
.
predict
(
repeats
=
50
)
# warmup
self
.
det_times
.
inference_time_s
.
start
()
result
=
self
.
predict
(
repeats
=
repeats
)
self
.
det_times
.
inference_time_s
.
end
(
repeats
=
repeats
)
# postprocess
result_warmup
=
self
.
postprocess
(
inputs
,
result
)
# warmup
self
.
det_times
.
postprocess_time_s
.
start
()
result
=
self
.
postprocess
(
inputs
,
result
)
self
.
det_times
.
postprocess_time_s
.
end
()
self
.
det_times
.
img_num
+=
1
cm
,
gm
,
gu
=
get_current_memory_mb
()
self
.
cpu_mem
+=
cm
self
.
gpu_mem
+=
gm
self
.
gpu_util
+=
gu
else
:
# preprocess
self
.
det_times
.
preprocess_time_s
.
start
()
self
.
det_times
.
preprocess_time_s
.
start
()
inputs
=
self
.
preprocess
(
[
im
])
# should be list
inputs
=
self
.
preprocess
(
batch_image_list
)
self
.
det_times
.
preprocess_time_s
.
end
()
self
.
det_times
.
preprocess_time_s
.
end
()
# model prediction
# model prediction
...
@@ -266,10 +296,17 @@ class Detector(object):
...
@@ -266,10 +296,17 @@ class Detector(object):
self
.
det_times
.
postprocess_time_s
.
end
()
self
.
det_times
.
postprocess_time_s
.
end
()
self
.
det_times
.
img_num
+=
1
self
.
det_times
.
img_num
+=
1
st
,
ed
=
0
,
result
[
'boxes_num'
][
0
]
# start_index, end_index
for
_ind
in
range
(
sub_img_num
):
boxes_num
=
result
[
'boxes_num'
][
_ind
]
ed
=
boxes_num
shift_amount
=
slice_image_result
.
starting_pixels
[
_ind
]
shift_amount
=
slice_image_result
.
starting_pixels
[
_ind
]
result
[
'boxes'
][:,
2
:
4
]
=
result
[
'boxes'
][:,
2
:
4
]
+
shift_amount
result
[
'boxes'
][
st
:
ed
][:,
2
:
4
]
=
result
[
'boxes'
][
result
[
'boxes'
][:,
4
:
6
]
=
result
[
'boxes'
][:,
4
:
6
]
+
shift_amount
st
:
ed
][:,
2
:
4
]
+
shift_amount
merged_bboxs
.
append
(
result
[
'boxes'
])
result
[
'boxes'
][
st
:
ed
][:,
4
:
6
]
=
result
[
'boxes'
][
st
:
ed
][:,
4
:
6
]
+
shift_amount
merged_bboxs
.
append
(
result
[
'boxes'
][
st
:
ed
])
st
=
ed
merged_results
=
{
'boxes'
:
[]}
merged_results
=
{
'boxes'
:
[]}
if
combine_method
==
'nms'
:
if
combine_method
==
'nms'
:
...
@@ -392,7 +429,7 @@ class Detector(object):
...
@@ -392,7 +429,7 @@ class Detector(object):
if
not
os
.
path
.
exists
(
self
.
output_dir
):
if
not
os
.
path
.
exists
(
self
.
output_dir
):
os
.
makedirs
(
self
.
output_dir
)
os
.
makedirs
(
self
.
output_dir
)
out_path
=
os
.
path
.
join
(
self
.
output_dir
,
video_out_name
)
out_path
=
os
.
path
.
join
(
self
.
output_dir
,
video_out_name
)
fourcc
=
cv2
.
VideoWriter_fourcc
(
*
'mp4v'
)
fourcc
=
cv2
.
VideoWriter_fourcc
(
*
'mp4v'
)
writer
=
cv2
.
VideoWriter
(
out_path
,
fourcc
,
fps
,
(
width
,
height
))
writer
=
cv2
.
VideoWriter
(
out_path
,
fourcc
,
fps
,
(
width
,
height
))
index
=
1
index
=
1
while
(
1
):
while
(
1
):
...
...
deploy/python/utils.py
浏览文件 @
486121ea
...
@@ -199,7 +199,7 @@ def argsparser():
...
@@ -199,7 +199,7 @@ def argsparser():
parser
.
add_argument
(
parser
.
add_argument
(
"--match_metric"
,
"--match_metric"
,
type
=
str
,
type
=
str
,
default
=
'io
u
'
,
default
=
'io
s
'
,
help
=
"Combine method matching metric, choose in ['iou', 'ios']."
)
help
=
"Combine method matching metric, choose in ['iou', 'ios']."
)
return
parser
return
parser
...
...
ppdet/engine/trainer.py
浏览文件 @
486121ea
...
@@ -718,7 +718,8 @@ class Trainer(object):
...
@@ -718,7 +718,8 @@ class Trainer(object):
match_metric
=
'iou'
,
match_metric
=
'iou'
,
draw_threshold
=
0.5
,
draw_threshold
=
0.5
,
output_dir
=
'output'
,
output_dir
=
'output'
,
save_results
=
False
):
save_results
=
False
,
visualize
=
True
):
self
.
dataset
.
set_slice_images
(
images
,
slice_size
,
overlap_ratio
)
self
.
dataset
.
set_slice_images
(
images
,
slice_size
,
overlap_ratio
)
loader
=
create
(
'TestReader'
)(
self
.
dataset
,
0
)
loader
=
create
(
'TestReader'
)(
self
.
dataset
,
0
)
...
@@ -771,40 +772,41 @@ class Trainer(object):
...
@@ -771,40 +772,41 @@ class Trainer(object):
for
key
in
[
'im_shape'
,
'scale_factor'
,
'im_id'
]:
for
key
in
[
'im_shape'
,
'scale_factor'
,
'im_id'
]:
if
isinstance
(
data
,
typing
.
Sequence
):
if
isinstance
(
data
,
typing
.
Sequence
):
ou
ts
[
key
]
=
data
[
0
][
key
]
merged_resul
ts
[
key
]
=
data
[
0
][
key
]
else
:
else
:
ou
ts
[
key
]
=
data
[
key
]
merged_resul
ts
[
key
]
=
data
[
key
]
for
key
,
value
in
merged_results
.
items
():
for
key
,
value
in
merged_results
.
items
():
if
hasattr
(
value
,
'numpy'
):
if
hasattr
(
value
,
'numpy'
):
merged_results
[
key
]
=
value
.
numpy
()
merged_results
[
key
]
=
value
.
numpy
()
results
.
append
(
merged_results
)
results
.
append
(
merged_results
)
# visualize results
if
visualize
:
for
outs
in
results
:
for
outs
in
results
:
batch_res
=
get_infer_results
(
outs
,
clsid2catid
)
batch_res
=
get_infer_results
(
outs
,
clsid2catid
)
bbox_num
=
outs
[
'bbox_num'
]
bbox_num
=
outs
[
'bbox_num'
]
start
=
0
start
=
0
for
i
,
im_id
in
enumerate
(
outs
[
'im_id'
]):
for
i
,
im_id
in
enumerate
(
outs
[
'im_id'
]):
image_path
=
imid2path
[
int
(
im_id
)]
image_path
=
imid2path
[
int
(
im_id
)]
image
=
Image
.
open
(
image_path
).
convert
(
'RGB'
)
image
=
Image
.
open
(
image_path
).
convert
(
'RGB'
)
image
=
ImageOps
.
exif_transpose
(
image
)
image
=
ImageOps
.
exif_transpose
(
image
)
self
.
status
[
'original_image'
]
=
np
.
array
(
image
.
copy
())
self
.
status
[
'original_image'
]
=
np
.
array
(
image
.
copy
())
end
=
start
+
bbox_num
[
i
]
end
=
start
+
bbox_num
[
i
]
bbox_res
=
batch_res
[
'bbox'
][
start
:
end
]
\
bbox_res
=
batch_res
[
'bbox'
][
start
:
end
]
\
if
'bbox'
in
batch_res
else
None
if
'bbox'
in
batch_res
else
None
mask_res
,
segm_res
,
keypoint_res
=
None
,
None
,
None
mask_res
,
segm_res
,
keypoint_res
=
None
,
None
,
None
image
=
visualize_results
(
image
=
visualize_results
(
image
,
bbox_res
,
mask_res
,
segm_res
,
keypoint_res
,
image
,
bbox_res
,
mask_res
,
segm_res
,
keypoint_res
,
int
(
im_id
),
catid2name
,
draw_threshold
)
int
(
im_id
),
catid2name
,
draw_threshold
)
self
.
status
[
'result_image'
]
=
np
.
array
(
image
.
copy
())
self
.
status
[
'result_image'
]
=
np
.
array
(
image
.
copy
())
if
self
.
_compose_callback
:
if
self
.
_compose_callback
:
self
.
_compose_callback
.
on_step_end
(
self
.
status
)
self
.
_compose_callback
.
on_step_end
(
self
.
status
)
# save image with detection
# save image with detection
save_name
=
self
.
_get_save_image_name
(
output_dir
,
image_path
)
save_name
=
self
.
_get_save_image_name
(
output_dir
,
logger
.
info
(
"Detection bbox results save in {}"
.
format
(
image_path
)
save_name
))
logger
.
info
(
"Detection bbox results save in {}"
.
format
(
image
.
save
(
save_name
,
quality
=
95
)
save_name
))
start
=
end
image
.
save
(
save_name
,
quality
=
95
)
start
=
end
def
predict
(
self
,
def
predict
(
self
,
images
,
images
,
...
...
tools/eval.py
浏览文件 @
486121ea
...
@@ -115,7 +115,7 @@ def parse_args():
...
@@ -115,7 +115,7 @@ def parse_args():
parser
.
add_argument
(
parser
.
add_argument
(
"--match_metric"
,
"--match_metric"
,
type
=
str
,
type
=
str
,
default
=
'io
u
'
,
default
=
'io
s
'
,
help
=
"Combine method matching metric, choose in ['iou', 'ios']."
)
help
=
"Combine method matching metric, choose in ['iou', 'ios']."
)
args
=
parser
.
parse_args
()
args
=
parser
.
parse_args
()
return
args
return
args
...
...
tools/infer.py
浏览文件 @
486121ea
...
@@ -113,7 +113,7 @@ def parse_args():
...
@@ -113,7 +113,7 @@ def parse_args():
parser
.
add_argument
(
parser
.
add_argument
(
"--match_metric"
,
"--match_metric"
,
type
=
str
,
type
=
str
,
default
=
'io
u
'
,
default
=
'io
s
'
,
help
=
"Combine method matching metric, choose in ['iou', 'ios']."
)
help
=
"Combine method matching metric, choose in ['iou', 'ios']."
)
parser
.
add_argument
(
parser
.
add_argument
(
"--visualize"
,
"--visualize"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录