当前位置:   article > 正文

c++实现yolov5的OpenVINO部署_yolov5 c++部署

yolov5 c++部署

注意,在以下整个过程中,出现python错误提示缺少什么模块,就使用pip install 该模块!!!否则无法进行!!!

主要参考:
https://gitee.com/avBuffer/yolov5_cpp_openvino?_from=gitee_search#git%E9%A1%B9%E7%9B%AE%E4%BD%BF%E7%94%A8

1、首先进行模型训练

yolov5下载地址:https://github.com/ultralytics/yolov5

yolov5的模型训练参考:https://github.com/wudashuo/yolov5

2、将模型训练得到.pt格式文件转换成.onnx格式文件

参考:https://github.com/ultralytics/yolov5/issues/251

在yolov5主目录下运行以下命令:

python models/export.py --weights yolov5s.pt --img 640 --batch 1
  • 1

出现以下图示情况说明.pt格式文件转换成.onnx格式文件成功,会看到在yolov5主目录下多了yolov5s.onnx等文件
在这里插入图片描述

转换完成后可以使用Netron:https://github.com/lutzroeder/netron.git 进行可视化.对于陌生的模型,该可视化工具对模型结构的认识有很大的帮助。
在这里插入图片描述

3、onnx格式转换OpenVINO的xml和bin格式

首先需要安装OpenVINO,可以参考我的另外一篇博客:Ubuntu18安装OpenVINO https://blog.csdn.net/qq_40700822/article/details/115707156

安装完成后运行如下脚本实现.onnx模型到.xml.bin模型的转换。

python /opt/intel/openvino/deployment_tools/model_optimizer/mo_onnx.py --input_model yolov5.onnx  --output_dir /home/inbc
  • 1
踩坑案例:

如果执行完后可能会一直报错,并无法生成.xml.bin模型:
在这里插入图片描述
需要修改yolov5 yolov5/models/export.py文件中的opset_version设置把12改为10,即:

 torch.onnx.export(model, img, f, verbose=False, opset_version=10, input_names=['images'],
                          output_names=['classes', 'boxes'] if y is None else ['output'],
                          dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'},  # size(1,3,640,640)
                                        'output': {0: 'batch', 2: 'y', 3: 'x'}} if opt.dynamic else None)
  • 1
  • 2
  • 3
  • 4

然后重新执行一下命令:

python models/export.py --weights yolov5s.pt --img 640 --batch 1  
  • 1

导出成功,就可以看到主目录下已经生成了yolov5.onnx文件了。

然后在执行命令:

python /opt/intel/openvino/deployment_tools/model_optimizer/mo_onnx.py --input_model yolov5.onnx  --output_dir /home/inbc
  • 1
踩坑完毕

看到一下画面就说明.xml.bin文件导出成功了。

在这里插入图片描述

运行成功之后会获得.xml.bin文件,.xml.binOpenVINO中的模型存储方式。

获得了yolov5s.xmlyolov5s.bin就可以进行c++实现yolov5的OpenVINO部署了。

4、c++实现yolov5的OpenVINO部署

1、首先下载大佬做的部署:

https://github.com/fb029ed/yolov5_cpp_openvino
先测试一下大佬的代码是否可用。

直接编译demo中的cpp文件即可:

cd demo
mkdir build
cd build
cmake ..
make
  • 1
  • 2
  • 3
  • 4
  • 5

编译完成后就可以直接运行程序了:

./detect_test
  • 1

出现一下图像说明环境搭建的还算比较成功:
在这里插入图片描述

2、好了,可以把自己训练好的.pt模型转换为.onnx模型,进而在转换为.xml.bin再在demo中使用。

我用yolov5训练好的模型文件名为last_1000.pt

模型转换过程见上文。

1、修改main.cpp

首先需要修改main.cpp文件中的文件路径(大约在第6行,我这里使用的是last_1000.xml):

#include "detector.h"

int main(int argc, char const *argv[])
{
    Detector* detector = new Detector;
    string xml_path = "../res/last_1000.xml";
    detector->init(xml_path,0.1,0.5);
    /*
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

更改测试图片的路径,大约在程序的第28行左右:

    waitKey(1);
    }
    */
    Mat src = imread("../res/32.png");
    Mat osrc = src.clone();
    resize(osrc,osrc,Size(640,640));
    vector<Detector::Object> detected_objects;
    auto start = chrono::high_resolution_clock::now();
    detector->process_frame(src,detected_objects);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
2、修改detector.cpp

这里需要修改测试对象的种类,需要修改第15行左右的item_size为6,因为我的模型只训练了一个对象,所以是1+5=6item_size=n+5其中n为你模型训练的物品的种类。

const float *output_blob = blobMapped.as<float *>();
   //80个类是85,一个类是6,n个类是n+5
   //int item_size = 6;
   int item_size = 6;
    size_t anchor_n = 3;
    for(int n=0;n<anchor_n;++n)
        for(int i=0;i<net_grid;++i)
            for(int j=0;j<net_grid;++j)
            {
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

之后编译运行测试一下:

cd demo_02
mkdir build
cd build
cmake ..
make
  • 1
  • 2
  • 3
  • 4
  • 5

编译成功后,生成了detect_test文件,直接执行该文件:

./detect_test
  • 1

耗时间use 0.219407 s,(本人用的Vm的Ubuntu18虚拟机,分配了3个处理器)如果出现一下画面,那恭喜你!!就可以愉快的用C++使用yolov5的模型训练了。
接下来就可以在大佬的肩膀上仰望星空了( ̄▽ ̄)!
在这里插入图片描述

5、推理加速

1、使用核显GPU进行计算

在main.cpp的第86行左右。

_network =  ie.LoadNetwork(cnnNetwork, "CPU");
  • 1

改为

_network =  ie.LoadNetwork(cnnNetwork, "GPU");
  • 1

这样

如果OpenVINO环境配置设置无误程序应该可以直接运行.

检测环境是否配置无误的方法是运行:

cd /opt/intel/openvino/deployment_tools/demo
./demo_security_barrier_camera.sh
  • 1
  • 2

若成功运行则cpu环境正常.

./demo_security_barrier_camera.sh -d GPU 
  • 1

运行正常则gpu环境运行正常.

2、使用openmp进行并行化

在推理之外的数据预处理和解析中存在大量循环,这些循环都可以利用openmp进行并行优化.

模型优化如定点化为int8类型
在模型转换时通过设置参数可以实现模型的定点化.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/300274?site
推荐阅读
相关标签
  

闽ICP备14008679号