深度学习模型试跑(十):yolov5-deepsort-tensorrt(c++,vs2019版)

9 篇文章 1 订阅
8 篇文章 0 订阅

stay现场版

前言

最近在做生物图像的相关深度学习任务,感觉所有任务中细胞追踪的应用的难度最高,所以在此记录了一下;在此特别感谢这位大佬博主以及他的博文
码字不易,求‘一键三连’。
下面是相关的项目链接地址:
yolov5:
Yolov5_DeepSort_Pytorch:
tensorrtx:
deepsort_tensorrt:
yolov5-deepsort-tensorrt:

一.模型解读

yolov5做检测,deepsort做追踪。
yolov5
DeepSORT

二.模型训练

我的环境

os:		win10
cuda:	11.1
gpu:	RTX3090	
torch:	1.7.1+cu110
代码: 这里只需要训练yolov5的模型即可,而我选择的是yolov5中的l(s/m/l/x)模型

1.数据收集与转换

1.1数据收集

我的数据来自于CTMC: Cell Tracking with Mitosis Detection Dataset Challenge,该数据集是标准的MOT格式数据集。其中,gt文件夹对应的是标签,img1文件夹对应的是图片。下图是各类细胞的说明。
请添加图片描述

由于训练过yolov5经验的,都应该知道这类标签是不能直接使用的,需要数据转换。

1.2数据转换

这里我分两步走,首先参考这篇博客,将MOT17-Det数据集转成VOC的xml格式。这篇博客不仅详细地解释了MOT17Det数据集格式与Pascal VOC数据集格式,而且提供了将MOT17Det转换成VOC格式的代码。我这里建议将它的2.1图片重命名和移动2.2将标注转换成voc格式拷贝下来生成两个对应的脚本并依次运行,而且对原始数据做备份因为图片会转移,而且其中xml.write的地方记得换行符n和制表符t前面加个\。运行后会得到image集合(.jpg)和标签集合(.xml)。
请添加图片描述

第二步就是先划分好(tain,val,test)数据集,再将xml转换为txt,这个代码有很多,网上一找到处都是,这里我直接提供我的代码。

#coding=utf-8
import os
import random
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'data/Annotations'
txtsavepath = 'data/ImageSets'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
#ftrainval = open('data/ImageSets/trainval.txt', 'w')
ftest = open('data/ImageSets/test.txt', 'w')
ftrain = open('data/ImageSets/train.txt', 'w')
fval = open('data/ImageSets/val.txt', 'w')
for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

sets = ['train', 'test', 'val']
classes = ['T31', 'T32', 'T33', 'T34', 'T35', 'T36', 'T37', 'T38', 'T39', 'T310', 'T311', 'T312', 'T313', 'T314',
           'T315', 'T316', 'T317', 'T318', 'T319', 'T320', 'T321', 'T322', 'T323', 'T324', 'T325', 'T326', 'T327',
           'T328', 'T329', 'T330', 'T331', 'T332', 'T333', 'T334', 'T335', 'T336', 'T337', 'T338', 'T339', 'T340',
           'T341', 'T342', 'T343', 'T344', 'T345', 'T346', 'T347', 'T348', 'T349', 'T350', 'T351', 'T352',
           'T353']


def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def convert_annotation(image_id):
    in_file = open('data/Annotations/%s.xml' % (image_id))
    out_file = open('data/labels/%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


wd = getcwd()
print(wd)
for image_set in sets:
    if not os.path.exists('data/labels/'):
        os.makedirs('data/labels/')
    image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split()
    list_file = open('data/%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write('data/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

2.配置

可参考我之前写的一篇
主要修改train.py下面三行以及对应的配置文件。

    parser.add_argument('--weights', type=str, default='yolov5l.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='models/yolov5l_t3.yaml', help='model.yaml path')
    parser.add_argument('--data', type=str, default='data/t3.yaml', help='dataset.yaml path')
    parser.add_argument('--workers', type=int, default=0, help='maximum number of dataloader workers')#windows上要设为0

请添加图片描述
请添加图片描述

3.开始训练

运行train.py

tensorboard:
请添加图片描述
效果一如既往的好。

运行detect.py,看模型推理。
请添加图片描述

三.YOLOV5模型转换

首先是将自己训练出来的模型转成对应的engine,具体的实施过程我也是参考tensorrtx做的。
——tensorrtx
——win10下的具体实施细节
大家可以看win10下的具体实施细节,自己改写Cmakelist生成对应的项目;s顺带提一下我的cmake用的是3.17.1版本。

由于我的数据集是53个类,需要在yololayer.h中设置static constexpr int CLASS_NUM = 53;
因为我用的是yolov5中的l模型生成engine的命令,需要把最后一个参数设置为l,对应的是yolov5.cpp里面的else if (net[0] == ‘l’)

转换后可以在对应路径下使用yolov5.exe -d your.engine 你的测试图片来检测你的模型转换是否成功。

四.deepsort模型转换

这里全部参照
win10下需要做到一下几步。

git clone https://github.com/RichardoMrMu/deepsort-tensorrt.git
// 根据github的说明
cp {deepsort-tensorrt}/exportOnnx.py {deep_sort_pytorch}/
python3 exportOnnx.py
mv {deep_sort_pytorch}/deepsort.onnx {deepsort-tensorrt}/resources
cd {deepsort-tensorrt}
mkdir build

将工程中的CMakeLists_deepsort-tensorrt_win10.txt(注意修改里面的内容)改为CMakeLists.txt并删掉原始的CMakeLists.txt,然后打开cmake,进行Configure和Generate.
![请添加图片描述](https://img-blog.csdnimg.cn/c3a95ba6e8104d6789cc7789b853e95b.JPG?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6IuP5ZaC6IuP5ZaC6IuP5ZaCX-WImOacrOWyqQ==,size_17,color_FFFFFF,t_70,g_se,x_16请添加图片描述
用vs2019打开工程后,需要修改featuretensor.cpp 第66行为std::ifstream engineStream(enginePath, std::ios::binary);和deepsortenginegenerator.cpp第52行为serializeOutputStream.open(enginePath, std::ios::binary);
然后生成onnx2engine、demo项目对应的onnx2engine.exe、 demo.exe,并运行下面命令生成并测试engine.

onnx2engine.exe deepsort.onnx deepsort.engine
demo.exe deepsort.engine track.txt

请添加图片描述

五.整体模型运行

参照第二步,下图是我的运行效果,640*640的图推理延迟平均15ms,还是非常理想的。
请添加图片描述

  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值