windows下基于libtorch的yolov5 6.0的c++部署

windows下基于libtorch的yolov5 6.0的c++部署

1、概述

libtorch是pytorch的C++版本,在需要多进程、提高推理速度等需求下会比python语言更具有优势。本文根据较新的yolov5的6.0版本,利用其自带的export.py将已经训练好的权重文件通过libtorch进行部署推理,基本的环境软件版本如下:

  • windows 7或 windows 10
  • pytorch 1.10.2
  • libtorch 1.10.1 + CPU
  • opencv 4.5.5
  • libtorch-yolov5-master
  • Visual studio 2019
  • Cmake3.23.2

2、相关下载与安装

yolov5和pytorch的安装,可以直接在yolov5的官网或者github上下载并安装。

libtorch1.10.1下载安装

各种版本的libtorch下载地址:https://blog.csdn.net/weixin_43742643/article/details/115218126
注:Libtorch的版本尽量和你训练使用的虚拟环境中的pytorch版本一致。下载之前先去你的虚拟环境中查看Pytorch版本。此外1.10.1版本上述连接的博文中没有给出,可以直接修改后面的版本号,例如CPU-Release版本的地址为

https://download.pytorch.org/libtorch/cpu/libtorch-win-shared-with-deps-1.10.1%2Bcpu.zip

(1) 选择对应的版本
(2) 选择Release or Debug
(3) 选择CPU or CUDA(GPU)

下载解压后,文件夹如下图
windows下基于libtorch的yolov5 6.0的c++部署_第1张图片

opencv下载安装

[Opencv下载地址:https://opencv.org/releases/](
windows下基于libtorch的yolov5 6.0的c++部署_第2张图片
下载安装后,文件夹如下图windows下基于libtorch的yolov5 6.0的c++部署_第3张图片
libtorch-yolov5-master, Cmake3.23.2的安装可以详细参考博文【1】。

3、配置Visual studio 2019

如果不打算新建一个自己的项目,可以直接跳过当前章节,使用下一节中libtorch-yolov5-master的编译生成的vs的解决方案。

详细的Visual studio 2019配置流程可以参考博文【1】,需要注意的是需要将opencv和libtorch的文件夹路径改为你自己电脑上的路径,此外,由于我这里是release版本,在配置项目属性页时,需要注意版本与平台的对应关系。

由于我这里的opencv的版本是4.5.5,注意其中的.lib文件为:

opencv_world455d.lib(Debug)
opencv_world455.lib(Release)

Libtorch的版本不同,其库文件略有差异,需要注意不要直接复制粘贴,1.10.1版本的附加依赖项为:

c10.lib
torch.lib
asmjit.lib
caffe2_detectron_ops.lib
caffe2_module_test_dynamic.lib
clog.lib
cpuinfo.lib
dnnl.lib
fbgemm.lib
Caffe2_perfkernels_avx.lib
Caffe2_perfkernels_avx2.lib
Caffe2_perfkernels_avx512.lib
fbjni.lib
libprotobuf.lib
libprotobuf-lite.lib
libprotoc.lib
mkldnn.lib
pthreadpool.lib
pytorch_jni.lib
torch_cpu.lib
XNNPACK.lib

最后,编译成功运行Libtorch或者opencv提示缺少dll,可以将对应的dll复制到编译好的exe同目录下或者将以下两个路径加入到系统的PATH路径中

D:\AI_project\opencv\opencv\build\x64\vc15\bin;D:\AI_project\libtorch\lib

4、 编译libtorch-yolov5-master

基本的编译过程参考博文【2】(其中主要是通过cmake在不同平台下实现编译),得到的build文件夹为:
windows下基于libtorch的yolov5 6.0的c++部署_第4张图片
打开上图中的libtorch-yolov5.sln,以下主要对libtorch-yolov5的源码进行改动,以通过编译和适用自己训练的模型。

detector.h

由于未安装cuda,注释掉这两行,如果安装了cuda和cudnn就无需注释

//#include 
//#include 

修改了Run函数,增加了一个函数输入,目的是调整推理时,输入网络的图片尺寸大小

std::vector>
    Run(const cv::Mat& img, float conf_threshold, float iou_threshold, int image_size);

detector.cpp

对应的修改如下:
windows下基于libtorch的yolov5 6.0的c++部署_第5张图片
main.cpp

Demo函数的结尾部分,增加保存绘图的图片,并修改了cv的对话框的模式:

  cv::namedWindow("Result", cv::WINDOW_NORMAL);
  cv::imshow("Result", img);
  cv::imwrite(".//out.jpg", img);
  cv::waitKey(0);

main函数中,命令行解释部分,新增了“label”和“imgsz”,分别是标签文件所在的路径和输入网络的尺寸大小

int main(int argc, const char* argv[]) {
    cxxopts::Options parser(argv[0], "A LibTorch inference implementation of the yolov5");

    // TODO: add other args
    parser.allow_unrecognised_options().add_options()
            ("label", "*.name path", cxxopts::value()->default_value("..//..//weights//coco.names"))
            ("weights", "model.torchscript.pt path", cxxopts::value())
            ("source", "source", cxxopts::value())
            ("conf-thres", "object confidence threshold", cxxopts::value()->default_value("0.4"))
            ("iou-thres", "IOU threshold for NMS", cxxopts::value()->default_value("0.5"))
            ("gpu", "Enable cuda device or cpu", cxxopts::value()->default_value("false"))
            ("view-img", "display results", cxxopts::value()->default_value("false"))
            ("imgsz", "image size for network input", cxxopts::value()->default_value("640"))
            ("h,help", "Print usage");

    auto opt = parser.parse(argc, argv);

    if (opt.count("help")) {
        std::cout << parser.help() << std::endl;
        exit(0);
    }

    // check if gpu flag is set
    bool is_gpu = opt["gpu"].as();

    // set device type - CPU/GPU
    torch::DeviceType device_type;
    if (torch::cuda::is_available() && is_gpu) {
        device_type = torch::kCUDA;
    } else {
        device_type = torch::kCPU;
    }

    // load class names from dataset for visualization
    std::vector class_names = LoadNames(opt["label"].as());
    if (class_names.empty()) {
        return -1;
    }

    // load network
    std::string weights = opt["weights"].as();
    auto detector = Detector(weights, device_type);

    // load input image
    std::string source = opt["source"].as();
    cv::Mat img = cv::imread(source);
    if (img.empty()) {
        std::cerr << "Error loading the image!\n";
        return -1;
    }

    // run once to warm up
    std::cout << "Run once on empty image" << std::endl;
    int image_size = opt["imgsz"].as();
    auto temp_img = cv::Mat::zeros(img.rows, img.cols, CV_32FC3);
    detector.Run(temp_img, 1.0f, 1.0f, image_size);

    // set up threshold
    float conf_thres = opt["conf-thres"].as();
    float iou_thres = opt["iou-thres"].as();

    // inference
    auto result = detector.Run(img, conf_thres, iou_thres, image_size);

    // visualize detections
    if (opt["view-img"].as()) {
        Demo(img, result, class_names);
    }

    cv::destroyAllWindows();
    return 0;
}

修改之后,重新编译所有,在文件夹Release下生成了libtorch-yolov5.exe和相应的动态库文件。

5、libtorch-yolov5.exe的使用

打开python版本的yolov5文件夹下,打开cmd,并且cd到yolov5文件夹下,yolov5s.pt导出torchscript文件(libtorch读取的权重文件格式)的命令为:

 python export.py --weights yolov5s.pt --data ./data/coco.yaml --imgsz 640 --device cpu --nms --include torchscript

自己训练的参数权重为pcban.pt,但是输入的网络的图片大小是1280*1280,则导出命令为:

 python export.py --weights pcban.pt --data ./data/pcban.yaml --imgsz 1280 --device cpu --nms --include torchscript

将上述导出的 yolov5s.torchscript 和pcban.torchscript复制到weights权重文件下(知道这两个文件的路径就行,后续运行时直接改路径即可)
windows下基于libtorch的yolov5 6.0的c++部署_第6张图片
打开cmd,并且cd到自己电脑libtorch-yolov5-master/build/release下,
windows下基于libtorch的yolov5 6.0的c++部署_第7张图片
运行以下命令(注意修改自己的路径),在release目录上同时生成了对应的out.jpg图片:

libtorch-yolov5.exe --label ..//..//weights//coco.names --source ..//..//images//bus.jpg --imgsz 640 --weights ..//..//weights//yolov5s.torchscript --view-img

windows下基于libtorch的yolov5 6.0的c++部署_第8张图片


在weights权重文件下新建pcban.txt,并修改后缀名为.names,每行输入自己训练的标签名,自己训练的图片名为pcb_1.jpg,运行以下命令

libtorch-yolov5.exe --label ..//..//weights//pcban.names --source ..//..//images//pcb_1.jpg --imgsz 1280 --weights ..//..//weights//pcban.torchscript --view-img

主要参考博文

【1】https://blog.csdn.net/weixin_39931579/article/details/119862099?spm=1001.2014.3001.5501

【2】https://zhuanlan.zhihu.com/p/403293735

你可能感兴趣的:(人工智能,pytorch,深度学习,c++)