用MOT17训练yolov8

本文详细描述了如何使用YOLOv8算法对MOT17数据集进行训练,包括数据分割、标签转换、模型训练以及评估过程,并提及了将模型导出为ONNX格式以便后续跟踪。
摘要由CSDN通过智能技术生成

YOLOv8训练MOT17

数据准备

1.制作训练数据
将MOT17分割为image和label两个子文件,两个子文件夹分别放test、train、val。
convert.py将数据集分割,该文件放在MOT17路径下。

'''
创建以下四个目录,用于存放图片和标签
images/train
images/val
labels/train
labels/val
'''
import os
import shutil
import numpy as np
import configparser
if not os.path.exists('images'):
    os.makedirs('images/train')
    os.makedirs('images/val')
    os.makedirs('images/test')
if not os.path.exists('labels'):
    os.makedirs('labels/train')
    os.makedirs('labels/val')
    os.makedirs('labels/test')


def convert(imgWidth, imgHeight, left, top, width, height):
    x = (left + width / 2.0) / imgWidth
    y = (top + height / 2.0) / imgHeight
    w = width / imgWidth
    h = height / imgHeight
    return ('%.6f'%x, '%.6f'%y, '%.6f'%w, '%.6f'%h) # 保留6位小数


for mot_dir in os.listdir('train'):  # mot_dir是例如MOT17-02-FRCNN这种
    det_path = os.path.join('train', mot_dir, 'det/det.txt')  # det.txt路径
    dets = np.loadtxt(det_path, delimiter=',')  # 读取det.txt文件
    ini_path = os.path.join('train', mot_dir, 'seqinfo.ini')  # seqinfo.ini路径
    conf = configparser.ConfigParser()
    conf.read(ini_path)  # 读取seqinfo.ini文件
    seqLength = int(conf['Sequence']['seqLength'])  # MOT17-02-FRCNN序列的长度
    imgWidth = int(conf['Sequence']['imWidth'])  # 图片宽度
    imgHeight = int(conf['Sequence']['imHeight'])  # 图片长度
    for det in dets:
        frame_id, _, left, top, width, height = int(det[0]), det[1], det[2], det[3], det[4], det[5]
        box = convert(imgWidth, imgHeight, left, top, width, height)
        if '-' in ''.join(box) or float(box[0]) > 1.0 or float(box[1]) > 1.0 or float(box[2]) > 1.0 or float(
                box[3]) > 1.0:
            print(imgWidth, imgHeight, left, top, width, height)
            print(box)
            break
        image_name = mot_dir + '-' + '%06d' % frame_id + '.jpg'  # MOT17-02-FRCNN-000001.jpg
        label_name = mot_dir + '-' + '%06d' % frame_id + '.txt'  # MOT17-02-FRCNN-000001.txt
        oldimgpath = os.path.join('train', mot_dir, 'img1',
                                  '%06d' % frame_id + '.jpg')  # train/MOT17-02-FRCNN/img1/000001.jpg
        if frame_id <= seqLength//2:  # 前一半划分给训练集
            newimgpath = os.path.join('images', 'train', image_name)  # images/train/MOT17-02-FRCNN-000001.jpg
            labelpath = os.path.join('labels', 'train', label_name)  # labels/train/MOT17-02-FRCNN-000001.txt
        else:  # 后一半划分给验证集
            newimgpath = os.path.join('images', 'val', image_name)  # images/val/MOT17-02-FRCNN-000001.jpg
            labelpath = os.path.join('labels', 'val', label_name)  # labels/val/MOT17-02-FRCNN-000001.txt
        if not os.path.exists(newimgpath):  # 如果图片没复制过去,就复制,
            shutil.copyfile(oldimgpath, newimgpath)  # 把旧图片复制到新的地方
        with open(labelpath, 'a') as f:  # 写label文件
            f.write(f'0 {box[0]} {box[1]} {box[2]} {box[3]}\n')

for mot_dir in os.listdir('test'):  # mot_dir是例如MOT17-01-FRCNN这种
    det_path = os.path.join('test', mot_dir, 'det/det.txt')  # det.txt路径
    dets = np.loadtxt(det_path, delimiter=',')  # 读取det.txt文件
    ini_path = os.path.join('test', mot_dir, 'seqinfo.ini')  # seqinfo.ini路径
    conf = configparser.ConfigParser()
    conf.read(ini_path)  # 读取seqinfo.ini文件
    seqLength = int(conf['Sequence']['seqLength'])  # MOT17-01-FRCNN序列的长度
    imgWidth = int(conf['Sequence']['imWidth'])  # 图片宽度
    imgHeight = int(conf['Sequence']['imHeight'])  # 图片长度
    for det in dets:
        frame_id, _, left, top, width, height = int(det[0]), det[1], det[2], det[3], det[4], det[5]
        box = convert(imgWidth, imgHeight, left, top, width, height)
        if '-' in ''.join(box) or float(box[0]) > 1.0 or float(box[1]) > 1.0 or float(box[2]) > 1.0 or float(
                box[3]) > 1.0:
            print(imgWidth, imgHeight, left, top, width, height)
            print(box)
            break
        image_name = mot_dir + '-' + '%06d' % frame_id + '.jpg'  # MOT17-01-FRCNN-000001.jpg
        label_name = mot_dir + '-' + '%06d' % frame_id + '.txt'  # MOT17-01-FRCNN-000001.txt
        oldimgpath = os.path.join('test', mot_dir, 'img1',
                                  '%06d' % frame_id + '.jpg')  # test/MOT17-01-FRCNN/img1/000001.jpg

        newimgpath = os.path.join('images', 'test', image_name)  # images/test/MOT17-01-FRCNN-000001.jpg
        labelpath = os.path.join('labels', 'test', label_name)  # labels/test/MOT17-01-FRCNN-000001.txt

        if not os.path.exists(newimgpath):  # 如果图片没复制过去,就复制,
            shutil.copyfile(oldimgpath, newimgpath)  # 把旧图片复制到新的地方
        with open(labelpath, 'a') as f:  # 写label文件
            f.write(f'0 {box[0]} {box[1]} {box[2]} {box[3]}\n')

而后准备txt,存放各图片的路径。运行MOT17下的name.py

import os


def generate(dir, folder):
    files = os.listdir(dir)
    files.sort()
    print('****************')
    print('input :', dir)
    print('start...')
    listText = open(str(folder)+'.txt', 'a')
    for file in files:
        fileType = os.path.split(file)
        if fileType[1] == '.txt':
            continue
        name = '/home/sdc/zhuhuiwen_space/datasets/MOT17/images/'+str(folder)+'/'+file + '\n'
        listText.write(name)
    listText.close()
    print('down!')
    print('****************')

if __name__ == '__main__':
    outer_path = './images'  # 这里是你的图片的目录
    i = 0
    folderlist = os.listdir(outer_path)  # 列举文件夹
    for folder in folderlist:
        generate(os.path.join(outer_path, folder), folder)
        i += 1

数据集格式

2.制作MOT17.yaml
由于MOT只有行人一类,所以nc=1;path为各个txt文件下图像路径的根路径

# 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: /home/sdc/zhuhuiwen_space/datasets  # dataset root dir
train: /home/sdc/zhuhuiwen_space/datasets/MOT17/train.txt  # train images (relative to 'path')  6471 images
val: /home/sdc/zhuhuiwen_space/datasets/MOT17/val.txt  # val images (relative to 'path')  548 images
test: /home/sdc/zhuhuiwen_space/datasets/MOT17/test.txt  # test images (optional)  1610 images

nc: 1

# Classes
names: ['']

训练yolov8

###YOLOv8/yolov8.py
from ultralytics import YOLO

import sys
import argparse
import os
import os.path as osp
import time
import cv2
import torch

img=cv2.imread("")
# Load a model
model = YOLO("yolov8n.yaml")  # build a new model from scratch
model = YOLO("yolov8n.pt")  # load a pretrained model (recommended for training)
model.train(data="MOT17.yaml", epochs=100)  # train the model 
metrics = model.val()  # evaluate model performance on the validation set
results = model.predict(source=img,save=True,save_txt=True)  # predict on an image
success = model.export(format="onnx")  # export the model to ONNX format

若需要在之前训练好的模型基础上继续训练,则设resume=True

model=YOLO("./weights/best.pt")
# Use the model
model.train(data="MOT17.yaml", epochs=100, resume=True)  # train the model

终端执行yolov8.py,训练好的结果放在YOLOv8/run/train/weights

cd YOLOv8
python yolov8.py

应用yolov8

with torch.no_grad():
    timer.tic()
    outputs = self.model.predict(source=img1, save=True, save_txt=True)
    results = [None for _ in range(len(outputs))]
    for i, image_pred in enumerate(outputs):
        prediction=image_pred.boxes.data
    # outputs为Result形式,包括boxes、keys等
    #boxes为bounding boxes,包含xyxy(tlbr坐标) conf cls
    #boxes.data包含六列 xyxy conf cls
        if results[i] is None:
            results[i] = prediction 
        else:
            results[i] = torch.cat((results[i], prediction))
return results, img_info

后续track需要用到的score即prediction[ : , 4]。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值