This commit is contained in:
gao-hairui
2022-09-28 22:38:00 +08:00
parent b19eac977d
commit 14092d780d
8 changed files with 760 additions and 0 deletions

351
fire_detection/README.md Normal file
View File

@@ -0,0 +1,351 @@
# 火灾识别
## 1 介绍
### 1.1 概要描述
**火灾识别**项目是基于MindX SDK在华为云昇腾平台上进行开发并部署到昇腾Atlas200 DK上实现**对图像中是否为火灾场景进行识别**的功能。在Atlas200 DK上对火灾场景测试集进行推理整体精度为94.15%,达到功能要求。
### 1.2 模型介绍
项目中用于火灾识别的是DenseNet模型模型相关文件可以在此处下载https://dl.dropbox.com/s/6t17srif65vzqfn/firedetect-densenet121-pretrained.pt
### 1.3 实现流程
1、在昇腾云服务器上搭建开发环境设置环境变量配置mxVision、Ascend-CANN-toolkit。
2、下载模型https://dl.dropbox.com/s/6t17srif65vzqfn/firedetect-densenet121-pretrained.pt 将PyTorch模型转换为昇腾离线模型densenet.pt --> densemet.onnx --> densenet.om。
3、业务流程编排与配置。
4、python推理流程代码开发。
5、将项目移植至Atlas200 DK测试精度性能。
火灾识别SDK流程图如图1-3所示
<center>
<img style="border-radius: 0.3125em;
box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.08);"
src="pic/火灾检测SDK流程图.png">
<br>
<div style="color:orange; border-bottom: 1px #d9d9d9;
display: inline-block;
color: #999;
padding: 2px;">图1-3 火灾检测SDK流程图</div>
</center>
## 2 软件方案介绍
### 2.1 项目方案架构介绍
本项目架构主要流程为图片进入流中将图片解码之后放缩到特定尺寸再利用densenet模型对图像中是否为火灾场景进行推理最后输出结果。
表2.1 项目方案架构中各模块功能:
<center>
<div style="color:orange; border-bottom: 1px #d9d9d9;
display: inline-block;
color: #999;
padding: 2px;">表2.1 火灾检测SDK流程图</div>
| 序号 | 子系统 | 功能描述 |
|:---:|:---:|:---:|
|1| 图像输入 | 调用Mindx SDK的appsrc输入图片 |
|2| 图像解码 | 调用Mindx SDK的mxpi_imagedecoder用于图像解码当前只支持JPG/JPEG/BMP格式 |
|3| 图像放缩 | 调用Mindx SDK的mxpi_imageresize放缩到224*224大小 |
|4| 火灾识别 | 调用Mindx SDK的mxpi_tensorinfer选取torch框架下densenet模型对图像进行火灾预测 |
|5| 结果输出 | 调用Mindx SDK的appsink提供端口从流中获取数据用于输出结果 |
</center>
### 2.2 代码目录结构与说明
本工程名称为fire_detection,工程目录如下所示:
```
.
|-- README.md
|-- data
| |-- other
| `-- test
|-- envs
| `-- atc_env.txt
|-- main.py
|-- models
| `-- pth2onnx_310.py
|-- pipeline
| `-- fire.pipeline
|-- run.sh
`-- test.py
```
## 3 设置开发环境
此项目在昇腾310云服务器开发并移植至Atlas200 DK上运行需要在昇腾云服务器进行编译执行后在Atlas200 DK上搭**建运行环境**并将项目部署到Atlas200 DK。
### 3.1 环境变量设置
查看文件 fire_detection/env/atc_env.txt 进行环境变量配置:
```bash
# 执行ascend-toolkit的set_env.sh
. /home/HwHiAiUser/Ascend/ascend-toolkit/set_env.sh
# 导入SDK路径
export MX_SDK_HOME=${SDK安装路径}
export GST_PLUGIN_SCANNER="${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scanner"
export GST_PLUGIN_PATH="${MX_SDK_HOME}/opensource/lib/gstreamer-1.0":"${MX_SDK_HOME}/lib/plugins"
export LD_LIBRARY_PATH="${MX_SDK_HOME}/lib/modelpostprocessors":"${MX_SDK_HOME}/lib":"${MX_SDK_HOME}/opensource/lib":"${MX_SDK_HOME}/opensource/lib64":${LD_LIBRARY_PATH}
export PYTHONPATH=${MX_SDK_HOME}/python:$PYTHONPATH
```
### 3.2 densenet模型转换
**步骤1** 下载densenet模型下载地址https://dl.dropbox.com/s/6t17srif65vzqfn/firedetect-densenet121-pretrained.pt ,将*.pt模型放至 fire_detection/models/ 文件夹下。
**步骤2** 将*.pt模型转换为*.onnx模型,执行 fire_detection/models 下脚本 pth2onnx_310.py ,得到 densenet.onnx 模型。注意修改*.pt模型输入路径`MODEL_PATH = './models/firedetect-densenet121-pretrained.pt`,以及*.onnx模型输出路径`OUTPUT_MODEL_PATH = './models/densenet.onnx'`,将输出*.onnx模型保存在 ./models 文件夹下。
**步骤3** 执行`cd ./models`到 models 文件加下执行atc命令 `atc --model=densenet.onnx --framework=5 --output=densenet --insert_op_conf=fire.cfg --soc_version=Ascend310` 利用atc工具将 densenet.onnx 转换为 densenet.om 。atc转换模型时使用aipp预处理aipp配置内容 ./models/fire.cfg 如下:
```json
aipp_op {
aipp_mode: static
input_format : YUV420SP_U8
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 256
matrix_r0c1 : 0
matrix_r0c2 : 359
matrix_r1c0 : 256
matrix_r1c1 : -88
matrix_r1c2 : -183
matrix_r2c0 : 256
matrix_r2c1 : 454
matrix_r2c2 : 0
input_bias_0 : 0
input_bias_1 : 128
input_bias_2 : 128
related_input_rank : 0
mean_chn_0 : 0
mean_chn_1 : 0
mean_chn_2 : 0
min_chn_0: 102.127
min_chn_1: 94.401
min_chn_2: 87.184
var_reci_chn_0: 0.0137213737839432
var_reci_chn_1: 0.0142654369859985
var_reci_chn_2: 0.0143018549505871
}
```
### 3.3 进行图像推理
下载测试集data将data下的test和other文件夹放至 fire_detection/data 下,在 fire_detection 路径下下运行 main.py 脚本,从 fire.pipeline 流中得到推理结果。
## 4 设置运行环境
关于Atlas200 DK硬件说明https://support.huawei.com/enterprise/en/doc/EDOC1100223188/d8adcdca/product-introduction
整体流程为先进行SD制卡将Ubuntu烧入Atlas200 DK烧录成功后通过ssh连接到Atlas200 DK安装CANN和Mindx SDK工具并设置环境变量之后再根据需求安装相应依赖。
### 4.1 所需依赖准备
Atlas200 DK环境依赖软件和版本表4所示建议按顺序安装
<center>
<div style="color:orange; border-bottom: 1px #d9d9d9;
display: inline-block;
color: #999;
padding: 2px;">表4.1 运行环境依赖</div>
| 依赖软件 | 版本 | 说明 |
| :--------: | :-----: | :------------------------: |
| Ubuntu | 18.04.1 LTS | 用于烧入Atlas200 DK |
| CANN | 6.0.RC1 | 用于提供模型转换ATC工具 |
| Mindx SDK | 3.0.RC2 | 用于提供pipeline插件等工具 |
| Python | 3.9.12 | 用于运行*.py文件 |
| numpy | 1.21.5 | 用于处理数组运算 |
| opencv-python | 4.6.0.66 | 用于图片处理 |
</center>
### 4.2 进行SD制卡
通过SD卡制作功能可以自行制作Atlas 200 DK开发者板的系统启动盘完成Atlas 200 DK操作系统及驱动固件的安装。
一般制卡方式有两种分别为直接mksd制卡和利用dd镜像制卡后者更为快捷但无法充分地利用tf卡的空间如果需要较大存储空间更推荐前者。
1.mksd制卡https://www.hiascend.com/document/detail/zh/Atlas200DKDeveloperKit/1013/environment/atlased_04_0009.html
2.dd镜像制卡https://bbs.huaweicloud.com/forum/thread-139685-1-1.html
制卡成功后将SD卡插至Atlas200 DK卡槽插入电源启动开发板。
### 4.3 配置网络连接
进行网络配置前需要确保Atlas 200 DK已完成操作系统及驱动的安装通过制作SD卡的方式进行安装且已正常启动。
通过ssh连接至Atlas200 DK后配置Atlas200 DK连接网络https://www.hiascend.com/document/detail/zh/Atlas200DKDeveloperKit/1013/environment/atlased_04_0012.html
进行配置后通过`ping www.huaweicloud.com`检查是否配置成功。
注意如果进行网络共享时主机无法上网可能是Windows版本问题可以通过版本回退的方法解决。
### 4.4 开发环境搭建
ssh连接Atlas200 DK成功后安装CANN和Mindx SDK此时Atlas200 DK为davinci-mini环境建议`su root`到root用户下进行安装和配置环境变量。
注意CANN版本与Atlas200 DK环境匹配https://gitee.com/ascend/tools/blob/master/makesd/Version_Mapping_CN.md
1.下载并安装CANNhttps://www.hiascend.com/document/detail/zh/Atlas200DKDeveloperKit/1013/environment/atlased_04_0017.html
2.下载并安装Mindx SDK
※ 安装CANN并且环境设置成功后再执行如下步骤
1下载与CANN版本匹配的 Mindx SDKhttps://www.hiascend.com/zh/software/mindx-sdk/mxVision/community
2将下载的 *.run 移至Atlas200 DK执行 `cd /usr/local/` 在local文件夹下执行 `mkdir Mindx_SDK` 创建 Mindx_SDK 文件夹,将下载的 Ascend-mindxsdk_{version}_linux-aarch64.run 移至 /usr/local/Mindx_SDK 下。
3安装 mxVision :执行 `cd /usr/local/Mindx_SDK` 后为 Ascend-mindxsdk_{version}_linux-aarch64.run 添加执行权限 ,成功后再执行 `Ascend-mindxsdk_{version}_linux-aarch64.run --install`安装 mxVision 。
4配置环境变量安装成功后在 mxVision 路径下存在 set_env.sh ,用户在任意目录下执行` vi ~/.bashrc` 命令,打开 .bashrc 文件,在文件最后一行后面添加 `. /usr/local/Mindx_SDK/mxVision` ,执行 :wq! 命令保存文件并退出。执行 `source ~/.bashrc` 命令使其立即生效。
完成上述步骤后Atlas200 DK已成功安装CANN和Mindx SDK。
3.安装python、pip、opencv等依赖Atlas200 DK为mini环境建议通过miniconda安装其他库
1下载与Atlas200 DK Ubuntu版本对应的minicondahttps://docs.conda.io/en/latest/miniconda.html#linux-installers
2执行`exit`切换到HwHiAiUser用户下为下载的 Miniconda3-latest-Linux-x86_64.sh 添加执行权限。
3HwHiAiUser用户下安装miniconda`sh ./Miniconda3-latest-Linux-x86_64.sh`
4为root用户添加conda环境`su root`后进入root用户执行 `cat /home/HwHiAiUser/.bashrc` 查看HwHiAiUser用户的 .bashrc , 复制 >>> conda initialize >>> 至 <<< conda initialize <<< 的内容将复制内容粘贴至 ~/.bashrc 执行 `source ~/.bashrc` 为root添加conda环境
5将Atlas200 DK重启reset再次进入root用户即可看到conda环境
6利用conda在root用户下用`conda install`安装numpyopencv-python等库
Atlas200 DK已经成功安装相关依赖
## 5 部署与运行
**步骤1** 部署及环境设置
fire_detection 文件夹移植到Atlas200 DK的用户HwHiAiUser下执行命令 `su root` 进入root用户下(默认密码Mind@123)执行 `cd /home/HwHiAiUser/fire_detection` 进入fire_detection路径下
fire_detection应包含
```
.
|-- README.md
|-- data
| |-- other
| `-- test
|-- envs
| `-- atc_env.txt
|-- main.py
|-- models
| |-- densenet121-pretrained.pt
| |-- densenet.onnx
| |-- densenet.om
| `-- pth2onnx_310.py
|-- pipeline
| `-- fire.pipeline
|-- run.sh
`-- test.py
```
**步骤2** 推理运行
在执行步骤一命令后的路径下运行脚本 main.py 在开发板上进行推理
**步骤3** 输出结果
```
精度: 94.15041782729804 %
总耗时: 3534.153747000346 ms 总图片数: 359
平均单张耗时: 9.8444394066862 ms
```
精度为94.15%与原模型推理精度误差小于1%;平均图像单张耗时9.84ms,满足25 fps要求
## 6 常见问题
### 6.1 无法调用plugin插件
**问题描述:**
在Atlas200 DK上运行 mian.py 无法调用plugin插件
**解决方案:**
确保root环境下可以执行atc并且能够调用mindx后在root用户下执行 main.py 脚本文件
### 6.2 推理结果精度不达标
**问题描述:**
在开发环境的推理结果精度不达标
**解决方案:**
在利用atc工具进行模型转换时配置aipp提升模型精度
```json
aipp_op {
aipp_mode: static
input_format : YUV420SP_U8
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 256
matrix_r0c1 : 0
matrix_r0c2 : 359
matrix_r1c0 : 256
matrix_r1c1 : -88
matrix_r1c2 : -183
matrix_r2c0 : 256
matrix_r2c1 : 454
matrix_r2c2 : 0
input_bias_0 : 0
input_bias_1 : 128
input_bias_2 : 128
related_input_rank : 0
mean_chn_0 : 0
mean_chn_1 : 0
mean_chn_2 : 0
min_chn_0: 102.127
min_chn_1: 94.401
min_chn_2: 87.184
var_reci_chn_0: 0.0137213737839432
var_reci_chn_1: 0.0142654369859985
var_reci_chn_2: 0.0143018549505871
}
```

View File

@@ -0,0 +1,13 @@
# 执行ascend-toolkit的set_env.sh
. /home/HwHiAiUser/Ascend/ascend-toolkit/set_env.sh
# 导入SDK路径
export MX_SDK_HOME=${SDK安装路径}
export GST_PLUGIN_SCANNER="${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scanner"
export GST_PLUGIN_PATH="${MX_SDK_HOME}/opensource/lib/gstreamer-1.0":"${MX_SDK_HOME}/lib/plugins"
export LD_LIBRARY_PATH="${MX_SDK_HOME}/lib/modelpostprocessors":"${MX_SDK_HOME}/lib":"${MX_SDK_HOME}/opensource/lib":"${MX_SDK_HOME}/opensource/lib64":${LD_LIBRARY_PATH}
export PYTHONPATH=${MX_SDK_HOME}/python:$PYTHONPATH

150
fire_detection/main.py Normal file
View File

@@ -0,0 +1,150 @@
"""
# Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
import json
import os
import time
import cv2
import numpy as np
from StreamManagerApi import StreamManagerApi, MxDataInput, StringVector
import MxpiDataType_pb2 as MxpiDataType
# The following belongs to the SDK Process
streamManagerApi = StreamManagerApi()
# init stream manager
ret = streamManagerApi.InitManager()
if ret != 0:
print("Failed to init Stream manager, ret=%s" % str(ret))
exit()
else:
print("-----------------创建流管理StreamManager并初始化-----------------")
# create streams by pipeline config file
# load pipline
with open("./pipeline/fire.pipeline", 'rb') as f:
print("-----------------正在读取读取pipeline-----------------")
pipelineStr = f.read()
print("-----------------成功读取pipeline-----------------")
ret = streamManagerApi.CreateMultipleStreams(pipelineStr)
# Print error message
if ret != 0:
print("-----------------未能成功创建流-----------------")
print("-----------------Failed to create Stream, ret=%s-----------------" % str(ret) )
else:
print("-----------------成功创建流-----------------")
print("-----------------Create Stream Successfully, ret=%s-----------------" % str(ret) )
# Stream name
# 读取图片
if os.path.exists('./data/test.jpg') != 1:
print("-----------------未能读取图片-----------------")
print("-----------------The test image does not exist.-----------------")
STREAM_NAME = b'classication' # 流的名称
IN_PLUGIN_ID = 0
TEST_PATH = "./data/test"
# 统计时间、图片张数
TOTAL_TIME = 0
PIC_NUM = 0
RIGHT_NUM = 0
for path_1 in os.listdir(TEST_PATH):
dataInput = MxDataInput()
path_2 = os.path.join(TEST_PATH, path_1)
for file_ in os.listdir(path_2):
file__ = os.path.join(path_2, file_)
tmp_ = cv2.imread(file__)
print(file__)
file__ = file__.replace('.png', '.jpg')
cv2.imwrite(file__, tmp_)
with open(file__, 'rb') as f:
print("-----------------开始读取图片-----------------")
dataInput.data = f.read()
print("-----------------读取图片成功-----------------")
os.remove(file__)
# 发送数据
start_time = time.perf_counter() # 推理开始时间戳
# 目标输入插件Id即appsrc元件的编号
uniqueId = streamManagerApi.SendData(STREAM_NAME, IN_PLUGIN_ID, dataInput) # SendData接口将图片数据发送给appsrc元件
if uniqueId < 0:
print("-----------------数据未能发送至流-----------------")
print("-----------------Failed to send data to stream.-----------------")
exit()
else:
print("-----------------数据成功发送至流-----------------")
# 获取数据
keys = [b"mxpi_tensorinfer0"] # 设置GetProtobuf的MxProtobufIn列表
keyVec = StringVector()
for key in keys:
keyVec.push_back(key)
print("-----------------从流获取推理结果-----------------")
infer_result = streamManagerApi.GetProtobuf(STREAM_NAME, 0, keyVec) # 从流中取出对应插件的输出数据
if infer_result.size() == 0:
print("-----------------推理结果null-----------------")
print("-----------------infer_result is null-----------------")
exit()
if infer_result[0].errorCode != 0:
print("-----------------推理结果error-----------------")
print("-----------------GetProtobuf error. errorCode=%d-----------------" % (
infer_result[0].errorCode))
exit()
tensorList = MxpiDataType.MxpiTensorPackageList()
tensorList.ParseFromString(infer_result[0].messageBuf)
prediction = np.frombuffer(tensorList.tensorPackageVec[0].tensorVec[0].dataStr, dtype = np.float32)
prediction_shape = tensorList.tensorPackageVec[0].tensorVec[0].tensorShape
prediction = np.reshape(prediction, prediction_shape)
if prediction[0][0] < 0.5:
print("predictno fire")
else:
print("predictfire")
end_time = time.perf_counter() # 推理结束时间戳
sigTime = (end_time - start_time) * 1000 # 单张图片好费时间
if(sigTime >= 40):
print("singal pic time out")
TOTAL_TIME = TOTAL_TIME + sigTime # 总耗费时间
PIC_NUM = PIC_NUM + 1 # 图片数量计数
print("耗时时间:", str(sigTime), "ms")
if '0_nofire' in file__ and prediction[0][0] < 0.5:
RIGHT_NUM = RIGHT_NUM + 1
if '1_fire' in file__ and prediction[0][0] >= 0.5:
RIGHT_NUM = RIGHT_NUM + 1
# Destroy All Streams
print("-----------------Destroy All Streams-----------------")
streamManagerApi.DestroyAllStreams()
print("精度:", RIGHT_NUM/PIC_NUM*100, "%")
print("总耗时:", TOTAL_TIME, "ms 总图片数:", PIC_NUM)
print("平均单张耗时:", TOTAL_TIME / PIC_NUM, "ms")
# *******************************************************************

View File

@@ -0,0 +1,28 @@
aipp_op {
aipp_mode: static
input_format : YUV420SP_U8
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 256
matrix_r0c1 : 0
matrix_r0c2 : 359
matrix_r1c0 : 256
matrix_r1c1 : -88
matrix_r1c2 : -183
matrix_r2c0 : 256
matrix_r2c1 : 454
matrix_r2c2 : 0
input_bias_0 : 0
input_bias_1 : 128
input_bias_2 : 128
related_input_rank : 0
mean_chn_0 : 0
mean_chn_1 : 0
mean_chn_2 : 0
min_chn_0: 102.127
min_chn_1: 94.401
min_chn_2: 87.184
var_reci_chn_0: 0.0137213737839432
var_reci_chn_1: 0.0142654369859985
var_reci_chn_2: 0.0143018549505871
}

View File

@@ -0,0 +1,28 @@
"""
# Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
from torch.autograd import Variable
import torch.onnx
from models import FireClassifier
cpu = torch.device("cpu")
net = FireClassifier(backbone='densenet121', pretrained=False)
dummy_input = Variable(torch.randn(1, 3, 224, 224)).to(cpu)
INPUT_MODEL_PATH = './models/firedetect-densenet121-pretrained.pt'
OUTPUT_MODEL_PATH = './models/densenet.onnx'
state_dict = torch.load(INPUT_MODEL_PATH, map_location=torch.device('cpu'))
net.load_state_dict(state_dict)
torch.onnx.export(net, dummy_input, OUTPUT_MODEL_PATH,
input_names=["image"], output_names=["output"], verbose=True)

View File

@@ -0,0 +1,43 @@
{
"classication": {
"stream_config": {
"deviceId": "0"
},
"appsrc0": {
"props": {
"blocksize": "409600"
},
"factory": "appsrc",
"next": "mxpi_imagedecoder0"
},
"mxpi_imagedecoder0": {
"props": {
"deviceId": "0"
},
"factory": "mxpi_imagedecoder",
"next": "mxpi_imageresize0"
},
"mxpi_imageresize0": {
"props": {
"dataSource": "mxpi_imagedecoder0",
"resizeHeight": "224",
"resizeWidth": "224"
},
"factory": "mxpi_imageresize",
"next": "mxpi_tensorinfer0"
},
"mxpi_tensorinfer0": {
"props": {
"modelPath": "./models/densenet.om"
},
"factory": "mxpi_tensorinfer",
"next": "appsink0"
},
"appsink0": {
"props": {
"blocksize": "4096000"
},
"factory": "appsink"
}
}
}

1
fire_detection/run.sh Normal file
View File

@@ -0,0 +1 @@
python /home/HwHiAiUser/fire_detection/main.py

146
fire_detection/test.py Normal file
View File

@@ -0,0 +1,146 @@
"""
# Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
import json
import imghdr
import os
import time
import cv2
import numpy as np
from StreamManagerApi import StreamManagerApi, MxDataInput, StringVector
import MxpiDataType_pb2 as MxpiDataType
# The following belongs to the SDK Process
streamManagerApi = StreamManagerApi()
# init stream manager
ret = streamManagerApi.InitManager()
if ret != 0:
print("Failed to init Stream manager, ret=%s" % str(ret))
exit()
else:
print("-----------------创建流管理StreamManager并初始化-----------------")
# create streams by pipeline config file
# load pipline
with open("./pipeline/fire.pipeline", 'rb') as f:
print("-----------------正在读取读取pipeline-----------------")
pipelineStr = f.read()
print("-----------------成功读取pipeline-----------------")
ret = streamManagerApi.CreateMultipleStreams(pipelineStr)
# Print error message
if ret != 0:
print("-----------------未能成功创建流-----------------")
print("-----------------Failed to create Stream, ret=%s-----------------" % str(ret) )
else:
print("-----------------成功创建流-----------------")
print("-----------------Create Stream Successfully, ret=%s-----------------" % str(ret) )
# Stream name
STREAM_NAME = b'classication' # 流的名称
IN_PLUGIN_ID = 0
# CarInFlames-FireFighterHelmetCam4591.png 汽车火灾
# CarInFlames-FireFighterHelmetCam6896.png 汽车烟雾
# HelmetCam2ndAlarmDwellingFire2361 住宅火灾
# HelmetCam2ndAlarmDwellingFire179 住宅烟雾
# Ogdenhousefire7071 火灾
# Ogdenhousefire459 烟雾
# /home/luoyang1/fire_detection/images/test.jpg 大型火灾
TEST_PATH = '{图片路径}'
PICTURE = '{图片名称}'
TEST_PATH = TEST_PATH + PICTURE
PIC_TYPE = imghdr.what(TEST_PATH)
# 输入为png图片则转换为jpg再进行读取若为jpg直接读取
if PIC_TYPE == 'png':
tmp_ = cv2.imread(TEST_PATH)
TEST_PATH = TEST_PATH.replace('.png', '.jpg')
cv2.imwrite(TEST_PATH, tmp_)
dataInput = MxDataInput()
with open(TEST_PATH, 'rb') as f:
print("-----------------开始读取图片-----------------")
dataInput.data = f.read()
print("-----------------读取图片成功-----------------")
os.remove(TEST_PATH)
else:
dataInput = MxDataInput()
with open(TEST_PATH, 'rb') as f:
print("-----------------开始读取图片-----------------")
dataInput.data = f.read()
print("-----------------读取图片成功-----------------")
start_time = time.perf_counter()
# 目标输入插件Id即appsrc元件的编号
uniqueId = streamManagerApi.SendData(STREAM_NAME, IN_PLUGIN_ID, dataInput) # SendData接口将图片数据发送给appsrc元件
start_time = time.perf_counter() # 推理开始时间戳
if uniqueId < 0:
print("-----------------数据未能发送至流-----------------")
print("-----------------Failed to send data to stream.-----------------")
exit()
else:
print("-----------------数据成功发送至流-----------------")
# 获取数据
keys = [b"mxpi_tensorinfer0"] # 设置GetProtobuf的MxProtobufIn列表
keyVec = StringVector()
for key in keys:
keyVec.push_back(key)
print("-----------------从流获取推理结果-----------------")
infer_result = streamManagerApi.GetProtobuf(STREAM_NAME, 0, keyVec) # 从流中取出对应插件的输出数据
if infer_result.size() == 0:
print("-----------------推理结果null-----------------")
print("-----------------infer_result is null-----------------")
exit()
if infer_result[0].errorCode != 0:
print("-----------------推理结果error-----------------")
print("-----------------GetProtobuf error. errorCode=%d-----------------" % (
infer_result[0].errorCode))
exit()
tensorList = MxpiDataType.MxpiTensorPackageList()
tensorList.ParseFromString(infer_result[0].messageBuf)
prediction = np.frombuffer(tensorList.tensorPackageVec[0].tensorVec[0].dataStr, dtype = np.float32)
prediction_shape = tensorList.tensorPackageVec[0].tensorVec[0].tensorShape
prediction = np.reshape(prediction, prediction_shape)
end_time = time.perf_counter()
pre = prediction[0][0] * 100
if prediction[0][0] < 0.5:
PREDICT = "Prediction: no fire"
else:
PREDICT = "Prediction: fire"
# Destroy All Streams
print("-----------------Destroy All Streams-----------------")
streamManagerApi.DestroyAllStreams()
print(PREDICT)
print("耗时:", (end_time - start_time)*1000, "ms")