实战教程:win10环境下用TensorRT推理YOLOv5

2 篇文章 0 订阅
1 篇文章 0 订阅

本文章记录在win10环境下用TensorRT推理YOLOv5.
例子来源于大佬的项目:https://github.com/wang-xinyu/tensorrtx,但此工程是在ubuntu上开发,在win10部署上不友好,故特作此贴。此贴致敬清华大佬王鑫宇,向王鑫宇学习!

1. 项目工程环境

本文所用的环境如下:

WIN 10
CUDA 10.2
CuDnn 7.6.5
TensorRT 7.2.3.4
OpenCV 4.3.0
VS 2019

2. VS的环境配置

本文不使用cmake建立VS工程,而是自己手动建立VS工程。
因此在配置VS环境之前,需要自己建立一个新的VS工程,并将yolov5下的头文件和源文件添加到VS中,如下图所示。
注意:cu文件时用cuda
在这里插入图片描述

2.1 配置头文件
将TensorRT的头文件、OpenCV的头文件、CUDA的头文件分别配置到VS的包含目录中,如下图所示。
在这里插入图片描述
2.2 配置库目录
将TensorRT的库目录、OpenCV的库目录、CUDA的库目录分别配置到VS的库目录中,如下图所示。
在这里插入图片描述
2.3配置链接库
将TensorRT的链接库、OpenCV的链接库、CUDA的链接库分别配置到VS的附加依赖项中,如下图所示。
在这里插入图片描述
CUDA的链接库如下:

cublas.lib
cublasLt.lib
cuda.lib
cudadevrt.lib
cudart.lib
cudart_static.lib
cudnn.lib
cudnn64_8.lib
cudnn_adv_infer.lib
cudnn_adv_infer64_8.lib
cudnn_adv_train.lib
cudnn_adv_train64_8.lib
cudnn_cnn_infer.lib
cudnn_cnn_infer64_8.lib
cudnn_cnn_train.lib
cudnn_cnn_train64_8.lib
cudnn_ops_infer.lib
cudnn_ops_infer64_8.lib
cudnn_ops_train.lib
cudnn_ops_train64_8.lib
cufft.lib
cufftw.lib
curand.lib
cusolver.lib
cusolverMg.lib
cusparse.lib
nppc.lib
nppial.lib
nppicc.lib
nppicom.lib
nppidei.lib
nppif.lib
nppig.lib
nppim.lib
nppist.lib
nppisu.lib
nppitc.lib
npps.lib
nvblas.lib
nvgraph.lib
nvjpeg.lib
nvml.lib
nvrtc.lib
OpenCL.lib

TensorRT的链接库如下:

nvparsers.lib
nvonnxparser.lib
nvinfer_plugin.lib
nvinfer.lib

OpenCV的链接库如下:

opencv_world430.lib

3. YOLOV5工程编译问题

3.1 dirent.h的问题
项目工程依赖头文件“dirent.h”,但dirent.h是ubuntu系统中的系统文件,windows系统没有。直接编译会出现如下错误:“dirent.h”: No such file or directory

没关系,只需要将 https://gitcode.net/mirrors/tronkko/dirent/-/tree/master/include下载下本地,将dirent.h直接放在工程目录下即可。同时将utils.h中的#include <dirent.h>改为#include “dirent.h”即可,如下图所示。
在这里插入图片描述

3.2 std::max和std::min的问题
在预处理定义中添加:NOMINMAX

同时,可能会有错误C4996 ‘localtime’: This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
别担心,在预处理定义中添加:_CRT_SECURE_NO_WARNINGS

在这里插入图片描述

3.3 cu文件的处理
wang-xinyu的yolov5工程中有cu文件,需要单独用CUDA编译,具体操作为:
右键项目 → 生成依赖项 → 生成自定义 → 勾选“CUDA 10.2”,如下图所示:
如果你在“生成自定义”中找不到CUDA,可以看参考这篇博客
在这里插入图片描述

对yololayer.cu和preprocess.cu文件单独执行如下操作:右键点击cu文件,选择属性,再选择CUDA C/C++
在这里插入图片描述
3.4 xxx
此时你去编译项目,会出现“YoloPluginCreator::mFC" may not be initialized”的报错,笔者在网上寻找答案,找到的答案是在cmakefiles.txt 增加add_definitions(-DAPI_EXPORTS),但是本文不依赖cmkake,因此只需要在macros.h文件中添加#define API_EXPORTS即可,如下图所示。
在这里插入图片描述

4.模型转换与推理

TensorRT理论上可以直接推理ONNX和engine模型。
在使用TensorRT推理模型之前,一般都有模型转换的过程。

yolov5的模型转换:首先将.pt 转.wts ,再将.wts转.engine。

注意:转换yolov5模型时依赖yolov5的原工程 https://github.com/ultralytics/yolov5
,需要将yolov5的原工程下载到本地。

https://github.com/wang-xinyu/tensorrtx 的yolov5工程下有脚本文件gen_wts.py,将gen_wts.py放到yolov5的原工程下,如下图所示:
在这里插入图片描述

在yolov5的原工程下,执行如下脚本,得到yolov5s.wts模型文件。

python gen_wts.py -w yolov5s.pt

把下载的yolov5.wts放在编译生成的release目录,运行下面的命令产生yolov5s.engine文件。

yolov5_tensorrt.exe -s yolov5s.wts yolov5s.engine s

模型推理:

yolov5_tensorrt.exe -d yolov5s.engine ./image_dir

GPU为英伟达GTX 1060,CPU为Intel i7八代,推理时间如下图。
在这里插入图片描述
推理效果图如下:
在这里插入图片描述

备注:本文借鉴了博客一博客二

  • 16
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
TensorRT是NVIDIA开发的高性能推理引擎,可以用于加速深度学习模型的推理。而YoloV5是一种目标检测模型,可以用于检测图像中的物体。 下面是使用TensorRT进行YoloV5推理的Python流程: 1. 导入必要的库和模块: ```python import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import cv2 import os import time ``` 2. 加载YoloV5模型并构建TensorRT引擎: ```python def build_engine(onnx_file_path, engine_file_path): TRT_LOGGER = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(TRT_LOGGER) explicit_batch = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) network = builder.create_network(explicit_batch) parser = trt.OnnxParser(network, TRT_LOGGER) with open(onnx_file_path, 'rb') as model: if not parser.parse(model.read()): for error in range(parser.num_errors): print(parser.get_error(error)) return None builder.max_batch_size = 1 builder.max_workspace_size = 1 << 30 engine = builder.build_cuda_engine(network) with open(engine_file_path, "wb") as f: f.write(engine.serialize()) return engine ``` 3. 加载TensorRT引擎: ```python def load_engine(engine_file_path): with open(engine_file_path, "rb") as f, trt.Runtime(TRT_LOGGER) as runtime: engine = runtime.deserialize_cuda_engine(f.read()) return engine ``` 4. 加载测试图片并预处理: ```python def preprocess(image, input_shape): image = cv2.resize(image, (input_shape[1], input_shape[0])) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = np.transpose(image, (2, 0, 1)).astype(np.float32) image /= 255.0 image = np.expand_dims(image, axis=0) return image ``` 5. 执行推理: ```python def do_inference(context, bindings, inputs, outputs, stream, batch_size=1): [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs] context.execute_async(bindings=bindings, batch_size=batch_size, stream_handle=stream.handle) [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs] stream.synchronize() return [out.host for out in outputs] ``` 6. 解析推理结果: ```python def postprocess(outputs, anchors, masks, input_shape, image_shape, conf_thres=0.5, iou_thres=0.5): num_classes = 80 num_anchors = 3 num_layers = 3 anchor_masks = masks anchors = np.array(anchors).reshape(num_layers, -1, 2) input_h, input_w = input_shape image_h, image_w, _ = image_shape scale_h, scale_w = image_h / input_h, image_w / input_w box_mins = np.zeros((0, 2)) box_maxes = np.zeros((0, 2)) box_classes = np.zeros((0)) box_scores = np.zeros((0)) for i in range(num_layers): grid_h, grid_w = input_h // 32 // (2 ** i), input_w // 32 // (2 ** i) outputs_i = outputs[i] outputs_i = np.reshape(outputs_i, (batch_size, num_anchors * (5 + num_classes), grid_h * grid_w)).transpose(0, 2, 1) outputs_i[..., :2] = 1 / (1 + np.exp(-outputs_i[..., :2])) outputs_i[..., 2:4] = np.exp(outputs_i[..., 2:4]) outputs_i[..., 4:] = 1 / (1 + np.exp(-outputs_i[..., 4:])) anchors_scale = anchors[i] anchors_scale = anchors_scale[np.newaxis, :, :] box_xy = outputs_i[..., :2] box_wh = outputs_i[..., 2:4] box_confidence = outputs_i[..., 4:5] box_class_probs = outputs_i[..., 5:] box_xy += (np.arange(grid_w, dtype=np.float32) + 0.5)[np.newaxis, :, np.newaxis] box_xy += (np.arange(grid_h, dtype=np.float32) + 0.5)[:, np.newaxis, np.newaxis] box_xy *= 32 * (2 ** i) box_wh *= anchors_scale box_wh *= np.array([image_w / input_w, image_h / input_h])[np.newaxis, np.newaxis, :] box_mins = np.concatenate([box_mins, box_xy - box_wh / 2], axis=0) box_maxes = np.concatenate([box_maxes, box_xy + box_wh / 2], axis=0) box_scores = np.concatenate([box_scores, box_confidence], axis=0) box_classes = np.concatenate([box_classes, np.argmax(box_class_probs, axis=-1).flatten()], axis=0) boxes = np.concatenate([box_mins, box_maxes], axis=-1) boxes /= np.array([scale_w, scale_h, scale_w, scale_h])[np.newaxis, :] nms_indices = cv2.dnn.NMSBoxes(boxes.tolist(), box_scores.flatten().tolist(), conf_thres, iou_thres) results = [] for i in nms_indices: i = i[0] box = boxes[i] score = box_scores.flatten()[i] label = box_classes.flatten()[i] results.append((box[0], box[1], box[2], box[3], score, label)) return results ``` 完整代码请参考:https://github.com/wang-xinyu/tensorrtx/tree/master/yolov5 需要注意的是,使用TensorRT进行YoloV5推理需要先将YoloV5模型转换为ONNX格式,然后再使用TensorRT构建引擎。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值