From ce2a78dd89c8fde1cab1d2d91115a1cca4d5bad2 Mon Sep 17 00:00:00 2001
From: pk_hk <82303451+pkhk-1@users.noreply.github.com>
Date: Sat, 9 Apr 2022 10:12:59 +0800
Subject: [PATCH] [pico] add onnxruntime demo (#5627)
---
configs/picodet/README.md | 21 +-
configs/picodet/README_en.md | 19 +-
.../third_engine/demo_onnxruntime/README.md | 43 ++++
.../demo_onnxruntime/coco_label.txt | 80 ++++++++
.../demo_onnxruntime/imgs/bus.jpg | Bin 0 -> 487438 bytes
.../demo_onnxruntime/imgs/dog.jpg | Bin 0 -> 163759 bytes
.../demo_onnxruntime/infer_demo.py | 193 ++++++++++++++++++
docs/images/bus.jpg | Bin 0 -> 490273 bytes
docs/images/dog.jpg | Bin 0 -> 185817 bytes
9 files changed, 336 insertions(+), 20 deletions(-)
create mode 100644 deploy/third_engine/demo_onnxruntime/README.md
create mode 100644 deploy/third_engine/demo_onnxruntime/coco_label.txt
create mode 100644 deploy/third_engine/demo_onnxruntime/imgs/bus.jpg
create mode 100644 deploy/third_engine/demo_onnxruntime/imgs/dog.jpg
create mode 100644 deploy/third_engine/demo_onnxruntime/infer_demo.py
create mode 100644 docs/images/bus.jpg
create mode 100644 docs/images/dog.jpg
diff --git a/configs/picodet/README.md b/configs/picodet/README.md
index 7f4e6a539..90e36f64b 100644
--- a/configs/picodet/README.md
+++ b/configs/picodet/README.md
@@ -205,18 +205,17 @@ paddle2onnx --model_dir output_inference/picodet_s_320_coco_lcnet/ \
- 部署用的模型
-| 模型 | 输入尺寸 | ONNX( w/o 后处理) | Paddle Lite(fp32) | Paddle Lite(fp16) |
+| 模型 | 输入尺寸 | ONNX | Paddle Lite(fp32) | Paddle Lite(fp16) |
| :-------- | :--------: | :---------------------: | :----------------: | :----------------: |
-| PicoDet-XS | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
-| PicoDet-XS | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
-| PicoDet-S | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320_fp16.tar) |
-| PicoDet-S | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416_fp16.tar) |
-| PicoDet-M | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320_fp16.tar) |
-| PicoDet-M | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416_fp16.tar) |
-| PicoDet-L | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320_fp16.tar) |
-| PicoDet-L | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
-| PicoDet-L | 640*640 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_640_coco.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640_fp16.tar) |
-
+| PicoDet-XS | 320*320 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_320_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_320_fp16.tar) |
+| PicoDet-XS | 416*416 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_416_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_416_fp16.tar) |
+| PicoDet-S | 320*320 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_320_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320_fp16.tar) |
+| PicoDet-S | 416*416 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_416_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416_fp16.tar) |
+| PicoDet-M | 320*320 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_320_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320_fp16.tar) |
+| PicoDet-M | 416*416 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_416_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416_fp16.tar) |
+| PicoDet-L | 320*320 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_320_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320_fp16.tar) |
+| PicoDet-L | 416*416 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_416_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
+| PicoDet-L | 640*640 | [( w/ 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_640_lcnet_postprocessed.onnx) | [( w/o 后处理)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_640_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640_fp16.tar) |
### 部署
diff --git a/configs/picodet/README_en.md b/configs/picodet/README_en.md
index c1a9483fa..f9c5f6185 100644
--- a/configs/picodet/README_en.md
+++ b/configs/picodet/README_en.md
@@ -204,15 +204,16 @@ paddle2onnx --model_dir output_inference/picodet_s_320_coco_lcnet/ \
| Model | Input size | ONNX(w/o postprocess) | Paddle Lite(fp32) | Paddle Lite(fp16) |
| :-------- | :--------: | :---------------------: | :----------------: | :----------------: |
-| PicoDet-XS | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
-| PicoDet-XS | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
-| PicoDet-S | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320_fp16.tar) |
-| PicoDet-S | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416_fp16.tar) |
-| PicoDet-M | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320_fp16.tar) |
-| PicoDet-M | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416_fp16.tar) |
-| PicoDet-L | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320_fp16.tar) |
-| PicoDet-L | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
-| PicoDet-L | 640*640 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_640_coco.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640_fp16.tar) |
+| PicoDet-XS | 320*320 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_320_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_320_fp16.tar) |
+| PicoDet-XS | 416*416 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_416_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_xs_416_fp16.tar) |
+| PicoDet-S | 320*320 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_320_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_320_fp16.tar) |
+| PicoDet-S | 416*416 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_416_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_s_416_fp16.tar) |
+| PicoDet-M | 320*320 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_320_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_320_fp16.tar) |
+| PicoDet-M | 416*416 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_416_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_m_416_fp16.tar) |
+| PicoDet-L | 320*320 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_320_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_320_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_320_fp16.tar) |
+| PicoDet-L | 416*416 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_416_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_416_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_416_fp16.tar) |
+| PicoDet-L | 640*640 | [( w/ postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_640_lcnet_postprocessed.onnx) | [( w/o postprocess)](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_640_coco_lcnet.onnx) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640.tar) | [model](https://paddledet.bj.bcebos.com/deploy/paddlelite/picodet_l_640_fp16.tar) |
+
### Deploy
diff --git a/deploy/third_engine/demo_onnxruntime/README.md b/deploy/third_engine/demo_onnxruntime/README.md
new file mode 100644
index 000000000..bdf7a9432
--- /dev/null
+++ b/deploy/third_engine/demo_onnxruntime/README.md
@@ -0,0 +1,43 @@
+# PicoDet ONNX Runtime Demo
+
+本文件夹提供利用[ONNX Runtime](https://onnxruntime.ai/docs/)进行 PicoDet 部署与Inference images 的 Demo。
+
+## 安装 ONNX Runtime
+
+本demo采用的是 ONNX Runtime 1.10.0,可直接运行如下指令安装:
+```shell
+pip install onnxruntime
+```
+
+详细安装步骤,可参考 [Install ONNX Runtime](https://onnxruntime.ai/docs/install/)。
+
+## Inference images
+
+- 准备测试模型:根据[PicoDet](https://github.com/PaddlePaddle/PaddleDetection/tree/develop/configs/picodet)中【导出及转换模型】步骤,采用包含后处理的方式导出模型(`-o export.benchmark=False` ),并生成待测试模型简化后的onnx模型(可在下文链接中直接下载)。同时在本目录下新建```onnx_file```文件夹,将导出的onnx模型放在该目录下。
+
+- 准备测试所用图片:将待测试图片放在```./imgs```文件夹下,本demo已提供了两张测试图片。
+
+- 在本目录下直接运行:
+ ```shell
+ python infer_demo.py --modelpath ./onnx_file/picodet_s_320_lcnet_postprocessed.onnx
+ ```
+ 将会对```./imgs```文件夹下所有图片进行识别,并将识别结果保存在```./results```文件夹下。
+
+- 结果:
+
+
+
+
+## 模型下载
+
+| 模型 | 输入尺寸 | ONNX( w/ 后处理) |
+| :-------- | :--------: | :---------------------: |
+| PicoDet-XS | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_320_lcnet_postprocessed.onnx) |
+| PicoDet-XS | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_xs_416_lcnet_postprocessed.onnx) |
+| PicoDet-S | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_320_lcnet_postprocessed.onnx) |
+| PicoDet-S | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_s_416_lcnet_postprocessed.onnx) |
+| PicoDet-M | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_320_lcnet_postprocessed.onnx) |
+| PicoDet-M | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_m_416_lcnet_postprocessed.onnx) |
+| PicoDet-L | 320*320 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_320_lcnet_postprocessed.onnx) |
+| PicoDet-L | 416*416 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_416_lcnet_postprocessed.onnx) |
+| PicoDet-L | 640*640 | [model](https://paddledet.bj.bcebos.com/deploy/third_engine/picodet_l_640_lcnet_postprocessed.onnx) |
diff --git a/deploy/third_engine/demo_onnxruntime/coco_label.txt b/deploy/third_engine/demo_onnxruntime/coco_label.txt
new file mode 100644
index 000000000..ca76c80b5
--- /dev/null
+++ b/deploy/third_engine/demo_onnxruntime/coco_label.txt
@@ -0,0 +1,80 @@
+person
+bicycle
+car
+motorbike
+aeroplane
+bus
+train
+truck
+boat
+traffic light
+fire hydrant
+stop sign
+parking meter
+bench
+bird
+cat
+dog
+horse
+sheep
+cow
+elephant
+bear
+zebra
+giraffe
+backpack
+umbrella
+handbag
+tie
+suitcase
+frisbee
+skis
+snowboard
+sports ball
+kite
+baseball bat
+baseball glove
+skateboard
+surfboard
+tennis racket
+bottle
+wine glass
+cup
+fork
+knife
+spoon
+bowl
+banana
+apple
+sandwich
+orange
+broccoli
+carrot
+hot dog
+pizza
+donut
+cake
+chair
+sofa
+pottedplant
+bed
+diningtable
+toilet
+tvmonitor
+laptop
+mouse
+remote
+keyboard
+cell phone
+microwave
+oven
+toaster
+sink
+refrigerator
+book
+clock
+vase
+scissors
+teddy bear
+hair drier
+toothbrush
diff --git a/deploy/third_engine/demo_onnxruntime/imgs/bus.jpg b/deploy/third_engine/demo_onnxruntime/imgs/bus.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b43e311165c785f000eb7493ff8fb662d06a3f83
GIT binary patch
literal 487438
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