基于Nvidia Jetson orin nx的 YoloV7 tensorRt加速

准备环境

安装jetPack组件

Jetpack 是 Nvidia为 Jetson系列开发板开发的一款软件开发包,常用的开发工具基本都包括了,并在在安装 Jetpack的时候,会自动的将匹配版本的CUDA、cuDNN、TensorRT等。官方提供套件中默认已经安装,可以通过以下命令查看jetPack是否已经安装。

官网指导链接:How to Install JetPack :: NVIDIA JetPack Documentation

# 法一:需要已安装jtop
sudo jetson_release
# 法二:无需安装jtop 
sudo apt-cache show nvidia-jetack
配置cuda环境变量
# 配置cuda环境变量
sudo vim ~/.bashrc
# 在文本中末尾添加如下代码
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64
export PATH=$PATH:/usr/local/cuda/bin
export CUDA_HOME=$CUDA_HOME:/usr/local/cuda
​
#使该配置生效
sorce ~/.bashrc
​
# 查看cuda 版本
nvcc -V

配置cuDNN

虽然jetpack安装了cuDNN,但并没有将对应的头文件、库文件放到cuda目录,cuDNN的头文件在:/usr/include,库文件位于:/usr/lib/aarch64-linux-gnu。将头文件与库文件复制到cuda目录下

# 复制文件到cuda目录下
cd /usr/include && sudo cp cudnn* /usr/local/cuda/include
cd /usr/lib/aarch64-linux-gnu && sudo cp libcudnn* /usr/local/cuda/lib64
​
# 修改文件权限,修改复制完的头文件与库文件的权限,所有用户都可读,可写,可执行:
sudo chmod 777 /usr/local/cuda/include/cudnn.h 
sudo chmod 777 /usr/local/cuda/lib64/libcudnn*
​
# 重新软链接,这里的8.6.0和8对应安装的cudnn版本号和首数字
cd /usr/local/cuda/lib64
​
sudo ln -sf libcudnn.so.8.6.0 libcudnn.so.8
​
sudo ln -sf libcudnn_ops_train.so.8.6.0 libcudnn_ops_train.so.8
sudo ln -sf libcudnn_ops_infer.so.8.6.0 libcudnn_ops_infer.so.8
​
sudo ln -sf libcudnn_adv_train.so.8.6.0 libcudnn_adv_train.so.8
sudo ln -sf libcudnn_adv_infer.so.8.6.0 libcudnn_adv_infer.so.8
​
sudo ln -sf libcudnn_cnn_train.so.8.6.0 libcudnn_cnn_train.so.8
sudo ln -sf libcudnn_cnn_infer.so.8.6.0 libcudnn_cnn_infer.so.8
​
sudo ldconfig
​
#测试cudnn
sudo cp -r /usr/src/cudnn_samples_v8/ ~/
cd ~/cudnn_samples_v8/mnistCUDNN
sudo chmod 777 ~/cudnn_samples_v8
sudo make clean && sudo make
./mnistCUDNN
​
可能存在问题
  1. 编译时freeImage.h文件不存在

# 执行安装命令
sudo apt-get install libfreeimage3 libfreeimage-dev
查看tensorrt版本
import tensorrt
print(tensort.__version__)

部署步骤

1. 拉取代码
#拉取 yolo-tensorRt
git clone https://github.com/Monday-Leo/YOLOv7_Tensorrt
# 拉取yolo 代码
git clone https://github.com/WongKinYiu/yolov7
#将**YOLOv7_Tensorrt**下的**EfficientNMS.py**和**export_onnx.py**复制到**yolov7**下,导出含有#EfficientNMS的onnx模型。
python3 export_onnx.py --weights ./weights/yolov7.pt
​

注:

如果遇到:EfficientNMS_TRT type is missing, so it may result in wrong shape inference for the exported graph.异常时,需要安装以下依赖

pip install onnx-simplifier pip install coremltools pip install nvidia-pyindex pip install onnx-graphsurgeon

2. 生成engine模型文件
trtexec --onnx=./yolov7.onnx --saveEngine=./yolov7_fp16.engine --fp16 --workspace=200
3. 运行代码
在YOLOv7_Tensorrt 工程项目中新增trt_model文件夹,并将转换好的yolov7_f16.engine 拷贝到 文件下,修改infer.py代码段
import cv2
import tensorrt as trt
import torch
import numpy as np
from collections import OrderedDict,namedtuple

class TRT_engine():
    def __init__(self, weight) -> None:
        self.imgsz = [640,640]
        self.weight = weight
        self.device = torch.device('cuda:0')
        self.init_engine()

    def init_engine(self):
        # Infer TensorRT Engine
        self.Binding = namedtuple('Binding', ('name', 'dtype', 'shape', 'data', 'ptr'))
        self.logger = trt.Logger(trt.Logger.INFO)
        trt.init_libnvinfer_plugins(self.logger, namespace="")
        with open(self.weight, 'rb') as self.f, trt.Runtime(self.logger) as self.runtime:
            self.model = self.runtime.deserialize_cuda_engine(self.f.read())
        self.bindings = OrderedDict()
        self.fp16 = False
        for index in range(self.model.num_bindings):
            self.name = self.model.get_binding_name(index)
            self.dtype = trt.nptype(self.model.get_binding_dtype(index))
            self.shape = tuple(self.model.get_binding_shape(index))
            self.data = torch.from_numpy(np.empty(self.shape, dtype=np.dtype(self.dtype))).to(self.device)
            self.bindings[self.name] = self.Binding(self.name, self.dtype, self.shape, self.data, int(self.data.data_ptr()))
            if self.model.binding_is_input(index) and self.dtype == np.float16:
                self.fp16 = True
        self.binding_addrs = OrderedDict((n, d.ptr) for n, d in self.bindings.items())
        self.context = self.model.create_execution_context()

    def letterbox(self,im,color=(114, 114, 114), auto=False, scaleup=True, stride=32):
        # Resize and pad image while meeting stride-multiple constraints
        shape = im.shape[:2]  # current shape [height, width]
        new_shape = self.imgsz
        if isinstance(new_shape, int):
            new_shape = (new_shape, new_shape)
        # Scale ratio (new / old)
        self.r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
        if not scaleup:  # only scale down, do not scale up (for better val mAP)
            self.r = min(self.r, 1.0)
        # Compute padding
        new_unpad = int(round(shape[1] * self.r)), int(round(shape[0] * self.r))
        self.dw, self.dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
        if auto:  # minimum rectangle
            self.dw, self.dh = np.mod(self.dw, stride), np.mod(self.dh, stride)  # wh padding
        self.dw /= 2  # divide padding into 2 sides
        self.dh /= 2
        if shape[::-1] != new_unpad:  # resize
            im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
        top, bottom = int(round(self.dh - 0.1)), int(round(self.dh + 0.1))
        left, right = int(round(self.dw - 0.1)), int(round(self.dw + 0.1))
        self.img = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
        return self.img,self.r,self.dw,self.dh

    def preprocess(self,image):
        self.img,self.r,self.dw,self.dh = self.letterbox(image)
        self.img = self.img.transpose((2, 0, 1))
        self.img = np.expand_dims(self.img,0)
        self.img = np.ascontiguousarray(self.img)
        self.img = torch.from_numpy(self.img).to(self.device)
        self.img = self.img.float()
        return self.img

    def predict(self,img,threshold):
        img = self.preprocess(img)
        self.binding_addrs['images'] = int(img.data_ptr())
        self.context.execute_v2(list(self.binding_addrs.values()))
        nums = self.bindings['num_dets'].data[0].tolist()
        boxes = self.bindings['det_boxes'].data[0].tolist()
        scores =self.bindings['det_scores'].data[0].tolist()
        classes = self.bindings['det_classes'].data[0].tolist()
        num = int(nums[0])
        new_bboxes = []
        for i in range(num):
            if(scores[i] < threshold):
                continue
            xmin = (boxes[i][0] - self.dw)/self.r
            ymin = (boxes[i][1] - self.dh)/self.r
            xmax = (boxes[i][2] - self.dw)/self.r
            ymax = (boxes[i][3] - self.dh)/self.r
            new_bboxes.append([classes[i],scores[i],xmin,ymin,xmax,ymax])
        return new_bboxes

def visualize(img,bbox_array):
    for temp in bbox_array:
        xmin = int(temp[2])
        ymin = int(temp[3])
        xmax = int(temp[4])
        ymax = int(temp[5])
        clas = int(temp[0])
        score = temp[1]
        cv2.rectangle(img,(xmin,ymin),(xmax,ymax), (105, 237, 249), 2)
        img = cv2.putText(img, "class:"+str(clas)+" "+str(round(score,2)), (xmin,int(ymin)-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (105, 237, 249), 1)
    return img

def test(path):
    import os
    out = './runs'
    images = os.listdir(path)
    engine = TRT_engine("./trt_model/video_fp32.engine")
    for item in images:
        img = cv2.imread(f'{path}/{item}')
        results = engine.predict(img,threshold=0.25)
        img = visualize(img,results)
        cv2.imwrite(f'{out}/{item}',img)

test('./pictures')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/143799.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】超详细一文带小白轻松全面理解 [ 二叉搜索树 ]—— [从零实现&逐过程分析&代码演示简练易懂]

前言 大家好吖&#xff0c;欢迎来到 YY 滴数据结构系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴数据结构专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.二叉搜索树的基本概念…

MATLAB|科研绘图|山脊图

效果图 山脊图介绍 山脊图&#xff08;Ridge Plot&#xff09;&#xff0c;也被称为Joy Plot&#xff0c;是一种用于可视化数据分布的图表&#xff0c;特别是用于显示多个组的分布情况。在这种图表中&#xff0c;每个组的数据分布都通过平滑的密度曲线来表示&#xff0c;这些曲…

基于 Lua 写一个爬虫程序

你想要基于 Lua 写一个爬虫程序来爬取的内容。我可以给你一个基本的框架&#xff0c;但是请注意这只是一个示例&#xff0c;并且你可能需要根据实际情况进行调整。 -- 首先&#xff0c;我们需要引入一些必要的模块 local http require "socket.http" local json r…

Spring Boot项目优雅实现读写分离

文章目录 1. 读写分离简介2. Spring Boot集成MyBatis3. 配置读写分离数据源4. 定义数据源上下文5. 自定义注解和切面6. 在Service层使用注解7. 拓展与分析7.1 多数据源的选择7.2 事务的处理7.3 异常处理7.4 动态数据源切换7.5 Spring Boot版本适配 &#x1f389;欢迎来到架构设…

如何将 .SQL 文件导入到 IDEA自带的MySQL中

首先连接数据库新建数据库右键选择该数据库选择如下&#xff1a;找到对应的sql文件即可

工作常遇,Web自动化测试疑难解答,测试老鸟带你一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、自动化测试中隐…

mac项目流程管理 OmniPlan Pro 4 中文最新 for mac

在OmniPlan Pro 4中&#xff0c;用户可以创建详细的项目计划&#xff0c;包括任务、资源、时间表、预算等设置。同时&#xff0c;软件支持任务管理&#xff0c;让用户能够创建、编辑和删除任务&#xff0c;设置任务的优先级、依赖关系、持续时间、起始日期等。对于资源管理&…

记一次 .NET 某券商论坛系统 卡死分析

一&#xff1a;背景 1. 讲故事 前几个月有位朋友找到我&#xff0c;说他们的的web程序没有响应了&#xff0c;而且监控发现线程数特别高&#xff0c;内存也特别大&#xff0c;让我帮忙看一下怎么回事&#xff0c;现在回过头来几经波折&#xff0c;回味价值太浓了。 二&#…

图论17-有向图的强联通分量-Kosaraju算法

文章目录 1 概念2 Kosaraju算法2.1 在图类中设计反图2.2 强连通分量的判断和普通联通分量的区别2.3 代码实现 1 概念 2 Kosaraju算法 对原图的反图进行DFS的后序遍历。 2.1 在图类中设计反图 // 重写图的构造函数public Graph(TreeSet<Integer>[] adj, boolean dire…

又双叒!宏电5G RedCap工业智能网关获得首个基于RedCap终端场景的华为技术认证

近日&#xff0c;宏电Z2 V20 5G RedCap工业智能网关率先通过华为OpenLab全球开放实验室的系列严格验证流程&#xff0c;完成基于华为RedCap终端场景的兼容性测试&#xff0c;首个获得华为Cloud Open Labs授予的HUAWEI COMPATIBLE证书及其相关认证徽标使用权。 宏电5G RedCap工业…

Elasticsearch:检索增强生成 (Retrieval Augmented Generation -RAG)

作者&#xff1a;JOE MCELROY 什么是检索增强生成 (RAG) 以及该技术如何通过提供相关源知识作为上下文来帮助提高 LLMs 生成的响应的质量。 生成式人工智能最近取得了巨大的成功和令人兴奋的成果&#xff0c;其模型可以生成流畅的文本、逼真的图像&#xff0c;甚至视频。 就语…

【移远QuecPython】EC800M物联网开发板的硬件TIM定时器精准延时

【移远QuecPython】EC800M物联网开发板的硬件TIM定时器精准延时 文章目录 导入库定时器初始化延时函数定时中断回调调用附录&#xff1a;列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 首先 这个定时器是硬件底层级别的 优先级最高 如果调用 会导致GNSS等线程…

理疗养生服务预约小程序要如何做

不少人面对身体症状疼痛&#xff0c;往往不会选择去医院&#xff0c;而是去理疗养生馆&#xff0c;选择艾灸、拔罐、中药贴敷等方式治疗改善或减轻疼痛。随着人们对中医信赖度增强&#xff0c;理疗养生市场增长迅速。 而在增长的同时&#xff0c;我们也注意到理疗养生馆经营痛…

Java版B/S架构云his医院信息管理系统源码(springboot框架)

一、技术框架 ♦ 前端&#xff1a;AngularNginx ♦ 后台&#xff1a;JavaSpring&#xff0c;SpringBoot&#xff0c;SpringMVC&#xff0c;SpringSecurity&#xff0c;MyBatisPlus&#xff0c;等 ♦ 数据库&#xff1a;MySQL MyCat ♦ 缓存&#xff1a;RedisJ2Cache ♦ 消息队…

工作汇报怎么写?建议收藏

整体思路与模块&#xff1a; 背景/事件 成果展示 推动落实的方法论 收获与成长 存在的不足及改进措施 下一步工作安排 支持&#xff08;选&#xff09; 一、背景/事件 对于区分“功能性总结”和“应付性总结”&#xff0c;在背景/事件方面有一个关键点 是报告是否具有…

Linux 系统目录结构

Linux 系统目录结构 登录系统后&#xff0c;在当前命令窗口下输入命令&#xff1a; ls / 你会看到如下图所示: 以下是对这些目录的解释&#xff1a; /bin&#xff1a; bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。 /boot&#xff1a; 这里存放…

第二章 (导数与微分)

导数简介 路程与时间关系函数 就是 速度与时间关系函数 的 原函数。 路程与时间关系函数 求导 &#xff08;或者叫导函数&#xff09; —————求导—————> 就是 vt关系的导数 求导得到》导函数 导函数积分 得到 原函数 你一开始速度为0&#xff0c;然后速度不断…

Perl的LWP::UserAgent库爬虫程序怎么写

Perl的LWP::UserAgent库是一个用于发送HTTP请求的Perl模块。它可以用于编写Web爬虫、测试Web应用程序、自动化Web操作等。以下是一个简单的使用LWP::UserAgent库发送HTTP GET请求的Perl脚本的例子&#xff1a; #!/usr/bin/perluse strict; use warnings; use LWP::UserAgent;# …

【移远QuecPython】EC800M物联网开发板的音乐播放(PWM蜂鸣器播放生日快乐歌,Sound模块播放音频)

【移远QuecPython】EC800M物联网开发板的音乐播放&#xff08;PWM蜂鸣器播放生日快乐歌&#xff0c;Sound模块播放音频&#xff09; 效果&#xff1a; 【移远QuecPython】EC800M开发板外置功放重金属和PWM音调&#xff08;BUG调试记录&#xff09; 文章目录 PWM蜂鸣器播放播放…

Java 通过POI快速导入带图片的excel并且图片不会丢失

## 通过POI快速导入带图片的excel并且图片不会丢失导入带图片的excel,这里也是研究了很久,在之前的博客中也有说明过,在项目使用过程中,发现很多时候导入响应很慢,而且每次导入图片都会丢失几张,所以又花了点时间研究修改了下,具体如下: 这边在导入时,通过自定义注解…