项目基础,网络传输协议、多目标分类classification、Yolo训练、Re-ID训练、多任务实现YOLOP

在这里插入图片描述

1、RTP

RTP全名是Real-time Transport Protocol(实时传输协议)
RTP协议常用于流媒体系统(配合RTCP协议或者RTSP协议)。因为RTP自身具有Time stamp所以在ffmpeg 中被用做一种formate.
每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。

RTP(Realtime Transport Protocol),实时传输协议
其专门针对实时流媒体而设计, RTP的基本功能是将几个实时数据流复用到一个UDP分组流中,这 个UDP流可以被发送给一台主机(单播模式),也可以被传送给多台目标主机(多播模式)。因为RTP仅仅封装成常规的UDP,理论上路由器不会对分组有任何特殊对待,但现在高级的路由设备都有针对RTP协议优化选项。RTP协议的时间戳机制,不仅减少了抖动的影响,而且也允许多个数据流相互之间的同步,这样可以很方便地基于I/O事件对视频图像进行字幕添加,网络摄像机往往将音视频编码数据封装成RTP分组。

RTCP(Realtime Transport Control Protocol)实时传输控制协议,其是RTP的姊妹协议。
它处理反馈、同步和用户界面等,但是不传输任何数据。它的主要功能是用来向源端提供有关延迟、抖动、带宽、拥塞和其它网络特性的反馈信息,编码进程可以充分利用这些信息。因此当网络状况较好时,可以提高数据速率(从而达到更好的质量),而当网络状况不好时,它可以减少数据速率。 通过连续的反馈信息,编码算法可以持续地作相应的调整,从而在当前条件下尽可能地提供最佳的质量。

RTSP(Real Time Streaming Protocol)实时流协议。
RTSP协议利用推式服务器(push server)方法,让音视频浏览端,发出一个请求,网络摄像机只是不停地向浏览端推送封装成RTP分组的音视频编码数据,网络摄像机可以用很小的系统开销实现流媒体传输。

HTTP(HyperText Transfer Protocol)超文本传输协议。
网络摄像机通过HTTP协议提供Web访问功能,很方便地将音视频数据经过复杂网络传输,但实时音视频支持很不理想。

UDP(User Datagram Protocol)数据报协议,是最基本的网络数据传输协议。
利用IP协议提供网络无连接服务,常用来封装实时性强的网络音视频数据,即使网络传输过程中发生分组丢失现象,在客户端也不会影响音视频浏览。

TCP(Transmission Control Protocol)传输控制协议,
利用IP协议提供面向连接网络服务,为在不可靠的互联网络上提供一个可靠的端到端字节流而设计。TCP协议往往要在服务端和客户端经过多次“握手”才能建立连接, 因此利用TCP传输实时性较强的音视频流开销较大 ,如果网络不稳定,音视频抖动的现象明显。利用其可靠性常用来传输网络摄像机管理命令,如PTZ,I/O设备控制命令。

2、multi-SVM和RestNet18和MobileNetV2

统计FLOPS

from torchvision.models import resnet18
from thop import profile
import torch
 
model = resnet18()
input = torch.randn(1, 3, 224, 224)
flops, params = profile(model, inputs=(input, ))
 
print(flops)

Resnet18 模型参数量 46.8MB resnet.pth
300300 size 1050ti 10.2ms
224
224 size 1050ti: 6.7ms

MobileNetV2 模型参数量13.6MB MobileNetV2.pth
224224 size 1050ti: 5.9ms
224
224 size 940mx: 9.8ms

IMageNet评估: Top-1 Params FLOPs
RepVGG-A0 72.41 8.3 M 1.4B 更快
ResNet-18 71.16 11.68M 1.8B

例如,利用Pytorch训练分类:
利用已有的数据读取函数

data_loader = torch.utils.data.DataLoader(
    torchvision.datasets.ImageFolder('traing_dataset',
       transform=torchvision.transforms.Compose([
                torchvision.transforms.Resize([28, 28]),       # 裁剪图片
                torchvision.transforms.Grayscale(1),           # 单通道
                torchvision.transforms.ToTensor(),             # 将图片数据转成tensor格式
                torchvision.transforms.Normalize(              # 归一化
                     (0.1307,), (0.3081,))
                ])),
    batch_size=10, shuffle=False)                  # 10张图片

文件夹读取函数,运用ImageFolder()和DataLoader()

from __future__ import print_function, division
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

train_transform = transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])

valid_transform=transforms.Compose([
            transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])

train_dataset =torchvision.datasets.ImageFolder(root='maize/train',transform=train_transform)
train_loader =DataLoader(train_dataset,batch_size=1, shuffle=True,num_workers=0)#Batch Size定义:一次训练所选取的样本数。 Batch Size的大小影响模型的优化程度和速度。

valid_dataset =torchvision.datasets.ImageFolder(root='maize/valid',transform=valid_transform)
valid_loader =DataLoader(valid_dataset,batch_size=1, shuffle=True,num_workers=0)

数据整理成如下格式:
在这里插入图片描述
在这里插入图片描述
另外的数据加载方式:

data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'valid': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

data_dir = 'maize'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
                                          data_transforms[x])
                  for x in ['train', 'valid']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
                                             shuffle=True, num_workers=1)
              for x in ['train', 'valid']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'valid']}
class_names = image_datasets['train'].classes

3、yolo训练

https://blog.csdn.net/weixin_41010198/article/details/106785253
https://blog.csdn.net/weixin_48994268/article/details/115282688

环境:

1:下载好yolov5文件后,cd到文件路径创建yolov5的环境
2:终端输入conda create -n yolov5 python==3.7,
3:进入环境conda activate yolov5,
4:安装requirements中的环境
pip install -r requirements.txt

数据集:

官方给出的训练数据的传入方式,有两种。
第一种直接将训练文件的路径写入txt文件传入。
第二种直接传入训练文件所在文件夹。
第一种coco数据及格式
我们可以用第二种:
mytrain
├── mycoco
│   ├── images
│   │   ├── train
│   │   └── val
│   └── labels
│       ├── train
│       └── val
└── yolov5

在这里插入图片描述
使用代码生产部分结构:

只需要准备好:
mycoco
├── all_images
├── all_xml
├── make_txt.py
└── train_val.py

其中make_txt.py

import os
import random
trainval_percent = 0.1  
train_percent = 0.9    
xmlfilepath = 'all_images'
txtsavepath = '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) #从所有list中返回tv个数量的项目
train = random.sample(trainval, tr)
if not os.path.exists('ImageSets/'):
    os.makedirs('ImageSets/')
ftrainval = open('ImageSets/trainval.txt', 'w')
ftest = open('ImageSets/test.txt', 'w')
ftrain = open('ImageSets/train.txt', 'w')
fval = open('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()

其中train_val.py
(将all_xml中xml文件转为txt文件存于all_labels文件夹中)

import xml.etree.ElementTree as ET
import pickle
import os
import shutil
from os import listdir, getcwd
from os.path import join
sets = ['train', 'trainval']
classes = ['car','chemicals vehicle','truck','bus','triangle warning sign','warning sign','warning slogan']
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('all_xml/%s.xml' % (image_id))
    out_file = open('all_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('all_labels/'):
        os.makedirs('all_labels/')
    image_ids = open('ImageSets/%s.txt' % (image_set)).read().strip().split()
    image_list_file = open('images_%s.txt' % (image_set), 'w')
    labels_list_file=open('labels_%s.txt'%(image_set),'w')
    for image_id in image_ids:
        image_list_file.write('%s.jpg\n' % (image_id))
        labels_list_file.write('%s.txt\n'%(image_id))
        convert_annotation(image_id) #如果标签已经是txt格式,将此行注释掉,所有的txt存放到all_labels文件夹。
    image_list_file.close()
    labels_list_file.close()


def copy_file(new_path,path_txt,search_path):#参数1:存放新文件的位置  参数2:为上一步建立好的train,val训练数据的路径txt文件  参数3:为搜索的文件位置
    if not os.path.exists(new_path):
        os.makedirs(new_path)
    with open(path_txt, 'r') as lines:
        filenames_to_copy = set(line.rstrip() for line in lines)
        # print('filenames_to_copy:',filenames_to_copy)
        # print(len(filenames_to_copy))
    for root, _, filenames in os.walk(search_path):
        # print('root',root)
        # print(_)
        # print(filenames)
        for filename in filenames:
            if filename in filenames_to_copy:
                shutil.copy(os.path.join(root, filename), new_path)

#按照划分好的训练文件的路径搜索目标,并将其复制到yolo格式下的新路径
copy_file('./images/train/','./images_train.txt','./all_image')
copy_file('./images/val/','./images_trainval.txt','./all_image')
copy_file('./labels/train/','./labels_train.txt','./all_labels')
copy_file('./labels/val/','./labels_trainval.txt','./all_labels')

最后安整的数据结构如下

mytrain
├── mycoco
│   ├── all_images
│   ├── all_labels
│   ├── all_xml
│   ├── ImageSets
│   │   ├── train.txt
│   │   ├── test.txt
│   │   ├── trainval.txt
│   │   └── val.txt
│   ├── images
│   │   ├── train
│   │   └── val
│   ├── labels
│        ├── train
│        └── val
│   ├── images_train.txt
│   ├── images_trainval.txt
│   ├── labels_train.txt
│   ├── labels_trainval.txt
│   ├── make_txt.py
│   └── train_val.py
└── yolov5

制作好的mycoco文件夹yolov5文件夹放同一级,如下:
在这里插入图片描述
最后生成训练所需的.ymal配置文件:

# Default dataset location is next to /yolov5:
#   /parent_folder
#     /mycoco
#     /yolov5


# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: ../mycoco/images/train/  
val: ../mycoco/images/val/  

# number of classes
nc: 7

# class names
names: ['car','chemicals vehicle','truck','bus','triangle warning sign','warning sign','warning slogan' ]

最后,最后,修改train.py里面对应的参数
在这里插入图片描述
可尝试1280 size
在这里插入图片描述

python detect.py --source data/images --weights model.pt --conf 0.25

出现错误:

ImportError: cannot import name 'amp' from 'torch.cuda' (/home/zyt/torch_tensorflow/py3torch/lib/python3.7/site-packages/torch/cuda/__init__.py)

修改 /models/common.py

#from torch.cuda import amp
from apex import amp

出现错误:

utils/plots.py", line 283, in plot_labels
    sns.pairplot(x, corner=True, diag_kind='auto', kind='hist', diag_kws=dict(bins=50), plot_kws=dict(pmax=0.9))
TypeError: pairplot() got an unexpected keyword argument 'corner'

正确的seaborn版本
pip3.7 install seaborn==0.11.1

4: 安装LabelImg
https://github.com/tzutalin/labelImg
> sudo apt-get install pyqt5-dev-tools sudo pip3 install -r
> requirements/requirements-linux-python3.txt pip3 install PyQt5 -i
> https://mirrors.aliyun.com/pypi/simple make qt5py3 python3 labelImg.py
> python3 labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]

使用方式:

Ctrl + u  加载目录中的所有图像,鼠标点击Open dir同功能
Ctrl + r  更改默认注释目标目录(xml文件保存的地址)
Ctrl + s  保存
Ctrl + d  复制当前标签和矩形框
space     将当前图像标记为已验证
w         创建一个矩形框
d         下一张图片
a         上一张图片
del       删除选定的矩形框
Ctrl++    放大
Ctrl--    缩小
↑→↓←        键盘箭头移动选定的矩形框

预定义类别在路径:

labelImg/data/predefined_classes.txt
5: deep sort

在这里插入图片描述
在这里插入图片描述

6: Re-ID 训练

行人重识别和人脸识别是类似的,刚开始接触的可以认为就是人脸换成行人的识别。

边缘计算可以用简单的HOG提取特征

或者优化特征提取网络,利用ShuffleNetV2-05代替原来的网络进行训练

有GPU情况下,也可直接训练原有的Re-ID模型:

数据集
Market-1501 数据集在清华大学校园中采集,夏天拍摄,在 2015 年构建并公开。它包括由6个摄像头(其中5个高清摄像头和1个低清摄像头)拍摄到的 1501 个行人、32668 个检测到的行人矩形框。每个行人至少由2个摄像头捕获到,并且在一个摄像头中可能具有多张图像。训练集有 751 人,包含 12,936 张图像,平均每个人有 17.2 张训练数据;测试集有 750 人,包含 19,732 张图像,平均每个人有 26.3 张测试数据。3368 张查询图像的行人检测矩形框是人工绘制的,而 gallery 中的行人检测矩形框则是使用DPM检测器检测得到的。该数据集提供的固定数量的训练集和测试集均可以在single-shot或multi-shot测试设置下使用。
在这里插入图片描述

行人对齐+重识别网络
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6: YOLOP

YOLOP: You Only Look Once for Panoptic Driving
Perception

测试数据集: BDD100K

https://arxiv.org/pdf/2108.11250.pdf

在这里插入图片描述

网络结果如下:
YOLOP采用 back,Neck和 head:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Train : BDD100k
Test : BDD100k

速度:TX2 23FPS
thind t470p gpu: python 500ms 0.5s
在这里插入图片描述
如果用
Train : BDD100k
Test : BDD100k

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如果用
Train : BDD100k
Test : CUlane
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7: 多模型融合代码:

检测模型 + 车道线模型:
效果如下:

速度:
thinpad T470p gpu 940mx
车道线50ms + 检测40ms = 90ms
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值