问题背景
这篇博客用来记录参加海赛C2过程中,如何实现在Jetson Nano上部署目标检测算法以及使用串口通信的方法。
数据标注与模型训练
YoloV5的使用与简单讲解
Yolov5模型目前在网络上已经经过了许多考验,且其Github官方也仍在不断更新,其相关平台的部署在官网也有很多教程,所以如果想在嵌入式平台部署目标检测以及分类网络,选择Yolov5可以带给我们极大的便利,这也是我选择使用Yolov5的原因。以下内容都是基于Yolov5目标检测模型的部署。
数据集的标注(使用Labelimg进行数据标注)
-
安装labelimg
这里是在Anaconda环境下的安装conda create -n label python==3.9 # 注意这里必须是python3.9版本,否则安装会导致无法正常使用 conda activate label # 激活环境 pip install labelimg # 使用pip安装labelimg labelimg # 这是打开labelimg界面的指令
-
打开labelimg并配置信息
输入命令:labelimg
之后会进入如下界面
- 这里主要需要配置上图中三个红圈选项
先简单介绍一下:- Open Dir:这里是打开你存放图片的文件夹
- Change Save Dir:这里是你图片标注的标签数据存放位置
- Yolo:这个是选择标注数据的格式,其中有很多个选项,根据自己模型训练所需的标签类型进行选择,这里选择yolo因为我训练的数据标签要求是Yolo类型。
- 这里主要需要配置上图中三个红圈选项
-
进行数据标注
当把上述配置准备工作完成后,就可以开始数据标注了啦,如下视频所示:
- W键:显示十字光标,出现十字光标后即可配合鼠标框住目标
- D键:下一张图片
- A键:上一张图片
- Ctrl+S键:对当前操作进行保存
- Ctrl+鼠标滚轮:对图片上鼠标所指区域进行放大和缩小操作
一般来说,知道上述四种快捷键即可帮助你进行快捷标注数据啦
进行训练
在标注完数据后,剩下的就是核心环节:训练模型
-
下载官方源码
首先从Yolov5官方Github上clone其代码:https://github.com/ultralytics/yolov5
可以使用两种方式下载其代码:-
方法一:使用git clone命令下载:
如上图所示,copy当前github下载链接,然后在你的虚拟环境下输入命令:git clone git@github.com:ultralytics/yolov5.git # 这条指令会在你的当前路径下载Yolov5文件
如果失败了,显示没有找到git命令,那么就是当前你的虚拟环境没有安装git,使用conda install git 或者 pip install git命令进行安装
如果失败了,显示是网络问题,那么可能你需要挂梯子才可以。如果仍然无法解决,那么就尝试开关重启。 -
方法二:直接从官网下载zip文件:
如上图所示,点击红圈选项,下载zip文件,随后将其解压即可得到Yolov5官方文件
-
-
配置模型训练相关信息
然后进入文件目录,在data文件夹下创建一个C2.yaml文件,其内容如下:# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license # COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics # Example usage: python train.py --data coco128.yaml # parent # ├── yolov5 # └── datasets # └── coco128 ← downloads here (7 MB) # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] path: ../datasets/coco128 # dataset root dir train: images/train2017 # train images (relative to 'path') 128 images val: images/train2017 # val images (relative to 'path') 128 images test: # test images (optional) # Classes names: 0: hole
文件路径以及内容详细参考以下图片:
其中:- path:是指根目录的路径
- train:是指要训练的图片存放位置
- val:是指要验证的图片存放位置(这里和train保持一致即可)
- name:类别存放位置,如图中所示:0表示目标类别索引(从0开始),hole表示其代表的类别名称
这里再附上一张训练数据存放的文件夹路径及内容:
这里只需要关注白色圈中的两个文件夹dataset与yolov5,其中路径相对位置如下:# parent # ├── yolov5 # └── datasets # └── coco128 # └── images # └── train2017 # 文件夹下是训练图片 # └── labels # └── train2017 # 文件夹下是训练图片对应的标注文件
之后按照官方文档进行配置你的虚拟环境,配置完成后即可使用终端在当前路径下输入以下命令进行训练:
python train.py --data C2.yaml --weights yolov5n.pt --cfg yolov5n.yaml --img 640 --batch-size 4
指令解释:
- –data:C2.yaml为前面所创建的文件,里面存放的是配置训练数据的相关内容
- –weights: yolov5n.pt是指使用官方的yolov5n预训练模型来进行迁移学习训练
- –cfg:yolov5n.yaml文件时模型的结构文件
- –img:640是指送进模型进行训练的图片尺寸,640表示640x640。注意此数字应为32的整数倍,不然训练会出错
- –batch-size:4是指一次送入模型训练的图片个数为4,这一项和你的GPU性能相联系,batch-size过大会导致你的GPU因为显存不够而无法训练。
如果上述命令输入后显示错误,一般来说是你的batch-size设置过大了,调小即可,如2或1。
当然还有一个前提是,你按照官方文档成功配置好了你的虚拟环境,如pytorch、cuda等。
训练完成后,你的模型存放在如下路径:
# parent
# ├── yolov5
# └── runs
# └── train
# └── exp # 不一定是exp,也有可能是exp+一个数字
# └── weights
# └── best.pt # 这是训练得到的最优的权重
安装ros,以进行串口通信
这里先附上jetson nano的引脚图
首先进行换源
- 备份源,防止操作错误以复用
cp /etc/apt/sources.list /etc/apt/sources.list.bak
- 编辑源文件,添加镜像
sudo gedit /etc/apt/sources.list
- 在打开的源文件中,将原内容删除,然后添加以下内容:
- 清华源:
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-proposed main restricted universe multiverse deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-proposed main restricted universe multiverse
- 中科大源:
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 deb http://mirrors.ustc.edu.cn/ubuntu-ports bionic main restricted universe multiverse # deb-src http://mirrors.ustc.edu.cn/ubuntu-ports bionic main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports bionic-updates main restricted universe multiverse # deb-src http://mirrors.ustc.edu.cn/ubuntu-ports bionic-updates main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports bionic-backports main restricted universe multiverse # deb-src http://mirrors.ustc.edu.cn/ubuntu-ports bionic-backports main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports bionic-security main restricted universe multiverse # deb-src http://mirrors.ustc.edu.cn/ubuntu-ports bionic-security main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports bionic-proposed main restricted universe multiverse deb-src http://mirrors.ustc.edu.cn/ubuntu-ports bionic-proposed main restricted universe multiverse
- 阿里源:
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 deb https://mirrors.aliyun.com/ubuntu-ports/ bionic main restricted universe multiverse # deb-src https://mirrors.aliyun.com/ubuntu-ports/ bionic main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu-ports/ bionic-updates main restricted universe multiverse # deb-src https://mirrors.aliyun.com/ubuntu-ports/ bionic-updates main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu-ports/ bionic-backports main restricted universe multiverse # deb-src https://mirrors.aliyun.com/ubuntu-ports/s bionic-backports main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu-ports/ bionic-security main restricted universe multiverse # deb-src https://mirrors.aliyun.com/ubuntu-ports/ bionic-security main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse
- 添加完成后,保存并退出。使用下述两条命令更新:
sudo apt update sudo apt upgrade -y
- 更换ROS的国内源(两条指令差不多,第一个是国外,第二个是中科大的源,选择一个即可)
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
- 然后再使用如下命令更新,完成后即配置成功
sudo apt update
获取密钥
有两种方法,推荐方法一
- 方法一:官网操作
可以获取最新的密钥,不用担心密钥是否过期,但可能受网络影响sudo apt install curl # 如果你没有安装curl的话,就使用这条命令 curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
- 方法二:网络教程
密钥可能过期,可以到网上搜索其他人发的密钥,试一试sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8D5A09DC9B929006
然后再使用如下命令对源软件列表进行更新(原先可能没密钥导致更新失败)
sudo apt update
安装ROS
- 安装全功能的ROS,这个安装包大概超过200M,执行以下命令:
sudo apt install ros-melodic-desktop-full
- 设置环境变量
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc source ~/.bashrc
- 安装相关的依赖
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential vim openconnect openssh-server
- ROS初始化
使用如下命令:sudo rosdep rosdep update
- ROS运行测试
在终端分别执行以下语句,测试小乌龟(具体作用我也不懂),只要能成功运行,那么表明你的ROS安装成功。roscore rosrun turtlesim turtlesim_node rosrun turtlesim turtle_teleop_key
如果出现 Command rosrun not found 即 rosrun 命令找不到的情况,输入以下命令即可:
sudo apt-get install rosbash
删除卸载ROS
当发现自己安装失败无法解决时,可以尝试重新开始,那么就需要把ROS重新装一遍了。
- 输入以下命令进行ROS的删除卸载:
sudo apt-get purge ros-* sudo rm -rf /etc/ros gedit ~/.bashrc # 打开该文件,删除带有melodic那一行即可 source ~/.bashrc # 刷新环境
可能遇到的问题报错
- Could not find a package configuration file provided by “serial“ with any serialConfig.cmake
- 输入以下命令
sudo apt-get install ros-melodic-serial
- 输入以下命令
- 无法定位功能包 E: Unable to locate package ros-melodic-***
- 方案一:首先使用以下命令更新一下,然后再次安装
sudo apt update
- 方案二:如果仍然无法下载,尝试输入以下命令,然后再次安装
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt update
- 方案三:进行换源
- 再次打开sources.list文件,使用以下命令:
sudo gedit /etc/apt/sources.list
- 在文件末尾加入以下内容:
deb http://packages.ros.org/ros-shadow-fixed/ubuntu bionic main
- 然后再次使用以下命令更新完后,再次安装:
sudo apt-get update
- 再次打开sources.list文件,使用以下命令:
- 方案一:首先使用以下命令更新一下,然后再次安装
- sudo rosdep init 找不到命令
- 首先查看rosdep是否安装,使用以下命令:
whereis rosdep
- 若没有显示任何信息,则表示没有安装,然后输入以下命令进行安装rosdep:
sudo apt install python-rosdep2 -y
- 首先查看rosdep是否安装,使用以下命令:
将模型部署在Jetson nano上
模型权重的文件类型转换
- 将模型权重由pt格式转换为wts格式
- 在yolov5文件夹中创建一个gen_wts.py文件,内容如下:
import sys import argparse import os import struct import torch from utils.torch_utils import select_device def parse_args(): parser = argparse.ArgumentParser(description='Convert .pt file to .wts') parser.add_argument('-w', '--weights', required=True, help='Input weights (.pt) file path (required)') parser.add_argument( '-o', '--output', help='Output (.wts) file path (optional)') parser.add_argument( '-t', '--type', type=str, default='detect', choices=['detect', 'cls', 'seg'], help='determines the model is detection/classification') args = parser.parse_args() if not os.path.isfile(args.weights): raise SystemExit('Invalid input file') if not args.output: args.output = os.path.splitext(args.weights)[0] + '.wts' elif os.path.isdir(args.output): args.output = os.path.join( args.output, os.path.splitext(os.path.basename(args.weights))[0] + '.wts') return args.weights, args.output, args.type pt_file, wts_file, m_type = parse_args() print(f'Generating .wts for {m_type} model') # Load model print(f'Loading {pt_file}') device = select_device('cpu') model = torch.load(pt_file, map_location=device) # Load FP32 weights model = model['ema' if model.get('ema') else 'model'].float() if m_type in ['detect', 'seg']: # update anchor_grid info anchor_grid = model.model[-1].anchors * model.model[-1].stride[..., None, None] # model.model[-1].anchor_grid = anchor_grid delattr(model.model[-1], 'anchor_grid') # model.model[-1] is detect layer # The parameters are saved in the OrderDict through the "register_buffer" method, and then saved to the weight. model.model[-1].register_buffer("anchor_grid", anchor_grid) model.model[-1].register_buffer("strides", model.model[-1].stride) model.to(device).eval() print(f'Writing into {wts_file}') with open(wts_file, 'w') as f: f.write('{}\n'.format(len(model.state_dict().keys()))) for k, v in model.state_dict().items(): vr = v.reshape(-1).cpu().numpy() f.write('{} {} '.format(k, len(vr))) for vv in vr: f.write(' ') f.write(struct.pack('>f', float(vv)).hex()) f.write('\n')
- 然后在你的虚拟环境下运行如下命令:
命令解释:python gen_wts.py -w ./runs/train/exp/weights/best.pt -o ./best.wts -t detect
- -w:是权重权重存放位置
- -o:是生成的wts类型权重的名称以及存放路径
- -t:是指定你的模型类型,detect表示目标检测网络,cls表示分类网络,seg表示分割网络
运行完毕后即可发现在当前路径下以及生成了一个best.wts文件
- 将wts格式权重转换为tensorrt的engine格式
这里需要使用Github上开源的相关工程文件,使用git clone将工程克隆到任意路径下,需要注意的是接下来的操作都是在Jetson系统上进行的。- 下载相关文件,使用命令(方法同上):
git clone https://github.com/wang-xinyu/tensorrtx
- 该工程目录如下:
# ├── tensorrtx # └── yolov5 # └── images # └── best.wts # 将上述生成得到的best.wts文件放入此路径 # └── plugin # 里面存放的适合yolov5模型结构相关的文件 # └── src # 里面是我们需要修改到的模型运行配置文件 # └── config.h # └── weights # └── best.pt
- 修改细节如下:
- config.h:将其中的kNumClass = 80修改为我们模型训练使用的类别数,这里我修改的kNumClass = 2;
- 然后在yolov5路径下使用如下命令将wts格式权重文件转换为engine格式权重文件
命令解释:mkdir build cd build cmake .. make sudo ./yolov5_det -s ../best.wts ../best.engine n
- 前四行命令:是使用cmake相关指令对相关文件进行编译,以生成可执行文件yolov5_det
- 最后一行命令:
- yolov5_det:目标检测的可执行文件,yolov5_cls与yolov5_seg同理;
- -s:应该是一种模型选择(即选择进行模型转换模型),…/best.wts表示我们前面操作生成的wts格式权重文件,即源文件;…/best.engine是目标文件,即生成转换得到的文件
- n:是我们yolov5模型的类型,这里由于我选择使用的是yolov5n模型,故为n。这里拓展一下若是yolov5m模型,则是m;yolov5l模型,则是l;其他类型同理即可。
注意:如果运行失败,请严格对照是否按照上述操作对相关文件进行修改。
- 之后使用如下命令检验生成的engine文件是否有问题:
命令解释:sudo ./yolov5_det -d ../best.engine ../samples
- -d:解释同上,是一种模型选择,即进行测试
- …/best.engine:我们生成的engine格式文件路径
- …/samples:我们要检测的图片存放路径,这里可自行创建该文件夹,并将自己的图片放入此文件夹
- 运行完后,会在当前路径下得到检测后的图片,可以自行观察检测模型是否有问题。
- 相关路径:
# ├── tensorrtx # └── yolov5 # └── images # └── best.wts # 将上述生成得到的best.wts文件放入此路径 # └── best.engine # 生成的engine文件 # └── samples # └── test1.jpg # └── test2.jpg # └── ... # └── plugin # 里面存放的适合yolov5模型结构相关的文件 # └── src # 里面是我们需要修改到的模型运行配置文件 # └── config.h # └── weights # └── best.pt # └── build # cmake相关语句后得到的文件 # └── yolov5_det # └── libmyplugins.so
- 下载相关文件,使用命令(方法同上):
选择框架——DeepStream
- 安装Deepstream5.x
- 附上下载地址:https://developer.nvidia.com/deepstream-getting-started
- 这里需要注意的是必须安装Deepstream5.x版本,最好是5.0,不然以下操作可能无效,
- 下载相关源文件
从Github上克隆他人开源的工程文件,使用命令(方法同上):
该工程目录如下(这里只给出要修改的文件):git clone git@github.com:DanaHan/Yolov5-in-Deepstream-5.0.git
# ├── Yolov5-in-Deepstream-5.0 # └── Deepstream5.0 # └── includes # └── nvdsinfer_custom_impl_Yolo # └── nvdsparsebbox_Yolo.cpp # └── Makefile # └── deepstream_app_config_yoloV5.txt
- 修改细节:
- 进入nvdsparsebbox_Yolo.cpp文件,内容如下,细节见注释:
... #include <cstdio> #include "serial/serial.h" #include <vector> ... static bool NvDsInferParseYoloV5( std::vector<NvDsInferLayerInfo> const& outputLayersInfo, NvDsInferNetworkInfo const& networkInfo, NvDsInferParseDetectionParams const& detectionParams, std::vector<NvDsInferParseObjectInfo>& objectList){ serial::Serial my_serial("/dev/ttyTHS1", 9600, serial::Timeout::simpleTimeout(50)); // 设置串口 /*if(my_serial.isOpen()){ // 测试串口是否成功打开 std::cout << "the location: X:" << std::endl; }*/ std::vector<Detection> res; nms(res, (float*)(outputLayersInfo[0].buffer), CONF_THRESH, NMS_THRESH); //std::cout<<"Nms done sucessfully----"<<std::endl; NvDsInferParseObjectInfo globalbbox; // 设置目标检测区域 globalbbox.classId = 0; globalbbox.left = static_cast<unsigned int>(160); globalbbox.top = static_cast<unsigned int>(120); globalbbox.width = static_cast<unsigned int>(320); globalbbox.height = static_cast<unsigned int>(240); globalbbox.detectionConfidence = 0.9; objectList.push_back(globalbbox); // 将目标检测区域当作目标,以在视频中得到显示 std::string output = "A"; // 设置标志位 unsigned int x = 100; // 设置初始目标的中心 unsigned int y = 100; unsigned int x_temp = 0; // 设置暂存变量 unsigned int y_temp = 0; double confidence_max = 0; // 按照置信度进行优先级选择 for(auto& r : res) { NvDsInferParseObjectInfo oinfo; oinfo.classId = r.class_id; if(oinfo.classId != 0) continue; oinfo.left = static_cast<unsigned int>(r.bbox[0]-r.bbox[2]*0.5f); oinfo.top = static_cast<unsigned int>(r.bbox[1]-r.bbox[3]*0.5f); oinfo.width = static_cast<unsigned int>(r.bbox[2]); oinfo.height = static_cast<unsigned int>(r.bbox[3]); oinfo.detectionConfidence = r.conf; x_temp = static_cast<unsigned int>(oinfo.left + oinfo.width*0.5f); // 计算目标的中心x,y y_temp = static_cast<unsigned int>(oinfo.top + oinfo.height*0.5f); if(x_temp>160 && x_temp<480 && y_temp>120 && y_temp< 360 && r.conf > confidence_max){ // 判断目标中心是否落入检测区域 x = x_temp;y = y_temp; confidence_max = r.conf; } objectList.push_back(oinfo); } output += std::to_string(x); // 将串口要发送的位置信息转换为合适格式 output += std::to_string(y); output += 'B'; // 设置停止位 std::vector<uint8_t> data(output.begin(), output.end()); // 对数据进行编码,以配合串口发送信息 // std::cout << data.size() << std::endl; my_serial.write(data.data(), data.size()); // 串口发送坐标信息 std::cout << "the location: X:" << x <<", Y:" << y << ", conf:" << confidence_max << ", link:" << data.data() << std::endl; // d打印当前串口发送的坐标信息,实际中可以将此行注释掉,因为print操作会影响程序运行速度 return true; }
- 将上述模型格式转换过程中生成的best.engine与libmyplugins.so文件复制到Deepstream5.0路径下
- 修改deepstream_app_config_yoloV5.txt文件,修改细节以及具体注释如下:
... [source0] enable=1 #Type - 1=CameraV4L2 2=URI 3=MultiURI type=1 # camera camera-width=640 # 相机获取视频的宽 camera-height=480# 相机获取视频的高 camera-fps-n=30 # 相机获取视频的帧率分子为30 camera-fps-d=1 # 相机获取视频的帧率分母为1,n与d配合,即30帧 #camera-v412-dev-node=0 #uri=file:/opt/nvidia/deepstream/deepstream-5.0/samples/streams/sample_1080p_h264.mp4 #uri=file:/home/nvidia/Documents/5-Materials/Videos/0825.avi num-sources=1 # 设置输入源数量,这里是1个 gpu-id=0 # 设置使用的GPU ID,这里是0号GPU # (0): memtype_device - Memory type Device # (1): memtype_pinned - Memory type Host Pinned # (2): memtype_unified - Memory type Unified cudadec-memtype=0 # 设置CUDA解码器使用的内存类型,这里是Device内存 ... # 这里是配置生成视频流 [streammux] ... width=640 height=480 ... ... [primary-gie] enable=1 gpu-id=0 model-engine-file=best.engine # 物体检测模型引擎文件 labelfile-path=labels.txt # 标签文件路径,包含类名,这里需要自己创建一个labels.txt文件 #batch-size=1 #Required by the app for OSD, not a plugin property bbox-border-color0=1;0;0;1 # 边界框边框颜色 bbox-border-color1=0;1;1;1 bbox-border-color2=0;0;1;1 bbox-border-color3=0;1;0;1 interval=0 # 推理间隔,单位毫秒 gie-unique-id=1 nvbuf-memory-type=0 config-file=config_infer_primary_yoloV5.txt # 包含更多设置的配置文件 [tracker] enable=0 tracker-width=512 tracker-height=320 ll-lib-file=/opt/nvidia/deepstream/deepstream-5.0/lib/libnvds_mot_klt.so # 根据自己的libnvds_mot_klt.so存放路径进行更改,一般而言不需要修改此项。如果是Deepstream5.1,可能需要修改为/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_mot_klt.so ...
- 在Deepstream5.0路径下创建一个labels.txt文件,内容如下:
解释:一个目标一行,即表示索引和内容hole
- 修改Makefile文件内容,细节以及注释如下:
上述Makefile文件的修改具体解释可以参考我的另一篇博客,里面详细记录了相关内容:https://sprli.github.io/2023/05/26/Cmake_Study/CUDA_VER?=10.2 ifeq ($(CUDA_VER),) $(error "CUDA_VER is not set") endif CC:= g++ NVCC:=/usr/local/cuda-$(CUDA_VER)/bin/nvcc CFLAGS:= -Wall -std=c++11 -shared -fPIC -Wno-error=deprecated-declarations CFLAGS+= -I../includes -I/usr/local/cuda-$(CUDA_VER)/include -I/opt/ros/melodic/include # 新增的,以成功在待编译的cpp文件中引入<serial/serial.h>头文件 LIBS:= -lnvinfer_plugin -lnvinfer -lnvparsers -L/usr/local/cuda-$(CUDA_VER)/lib64 -lcudart -lcublas -lstdc++fs -L/opt/ros/melodic/lib -lserial # 新增的,链接库文件/opt/ros/melodic/lib/libserial.so,以实现串口通信。 LFLAGS:= -shared -Wl,--start-group $(LIBS) -Wl,--end-group INCS:= $(wildcard *.h) SRCFILES:= nvdsinfer_yolo_engine.cpp \ nvdsparsebbox_Yolo.cpp \ trt_utils.cpp \ # yolo.cpp \ # 注释掉这两行,因为使用不到,并且使用的话会导致无法顺利通过编译。 # yoloPlugins.cpp # 注释掉这两行 TARGET_LIB:= libnvdsinfer_custom_impl_Yolo.so #TARGET_LIB:= libnvdsinfer_custom_impl_Yolo.so TARGET_OBJS:= $(SRCFILES:.cpp=.o) TARGET_OBJS:= $(TARGET_OBJS:.cu=.o) all: $(TARGET_LIB) %.o: %.cpp $(INCS) Makefile $(CC) -c -o $@ $(CFLAGS) $< %.o: %.cu $(INCS) Makefile $(NVCC) -c -o $@ --compiler-options '-fPIC' $< $(TARGET_LIB) : $(TARGET_OBJS) $(CC) -o $@ $(TARGET_OBJS) $(LFLAGS) clean: rm -rf $(TARGET_LIB)
- 进入nvdsparsebbox_Yolo.cpp文件,内容如下,细节见注释:
运行及使用
运行使用命令:
sudo LD_PRELOAD=/home/nano/Desktop/Yolov5-in-Deepstream-5.0/Deepstream5.0/libmyplugins.so:/opt/ros/melodic/lib/libserial.so deepstream-app -c /home/nano/Desktop/Yolov5-in-Deepstream-5.0/Deepstream5.0/deepstream_app_config_yoloV5.txt