初探yolov5
环境
pyton: 3.8.8
系统: windows11 64 位
yolov5环境安装
github地址: https://github.com/ultralytics/yolov5
安装三方库:
pip install ultralytics
clonegithub地址:
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install
**安装打标库: **
//下载labelimg
pip install labelimg
//运行labelimg
labelimg
数据准备(以游戏示例,进行打标)
将视频转为图片
# -*- coding: UTF-8 -*-
# @Time: 2024-08-06 15:18
# @Author: liupeng
# @File: 视频转图片2.py
# @desc:
# 导入所需要的库
import cv2
import numpy as np
video_path = "视频文件路径.pm4"
save_path = "保存的路径及命名"
# 定义保存图片函数
# image:要保存的图片名字
# addr;图片地址与相片名字的前部分
# num: 相片,名字的后缀。int 类型
def save_image(image, addr, num):
address = addr + str(num) + '.jpg'
cv2.imwrite(address, image)
# 读取视频文件 视频文件路径
videoCapture = cv2.VideoCapture(video_path)
# 通过摄像头的方式
# videoCapture=cv2.VideoCapture(1)
# 读帧
success, frame = videoCapture.read()
i = 0
timeF = 1
j = 0
while success:
i = i + 1
if (i % timeF == 0):
j = j + 1
save_image(frame, save_path, j) # 视频截成图片存放的位置
print('save image:', i)
success, frame = videoCapture.read()
使用labelimg对图片进行打标
运行labelimg:
# 进入对应的python环境下 输入
labelimg
打开后,界面如下:
常用快捷键:
注意: 标注的框要大小正好框住所要识别的物体,这有利于进行训练。
将标注文件转为txt文件(不知道是啥原理,但是要转一下)
# -*- coding: UTF-8 -*-
# @Time: 2024-08-06 23:01
# @Author: liupeng
# @File: 批量修改后缀.py
# @desc:
import os
import xml.etree.ElementTree as ET
import pickle
from os import listdir, getcwd
from os.path import join
import random
from shutil import copyfile
classes = ['role'] # 修改为打标签的标签
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 rename_file_extensions(directory, old_ext, new_ext):
"""
批量修改指定目录中所有文件的后缀名。
:param directory: 要处理的目录路径
:param old_ext: 当前文件的后缀名(包括点,如 '.txt')
:param new_ext: 要修改成的新后缀名(包括点,如 '.md')
"""
for filename in os.listdir(directory):
if filename.endswith(old_ext):
base = os.path.splitext(filename)[0]
new_filename = f"{base}{new_ext}"
old_path = os.path.join(directory, filename)
new_path = os.path.join(directory, new_filename)
convert_annotation(old_path, new_path)
# os.rename(old_path, new_path)
print(f"Renamed: {old_path} -> {new_path}")
def convert_annotation(old_file, new_file):
print('111')
# in_file = open('VOCdevkit/VOC2007/Annotations/%s.xml' %image_id)
in_file = open(old_file, encoding='UTF-8')
# out_file = open('VOCdevkit/VOC2007/YOLOLabels/%s.txt' %image_id, 'w')
out_file = open(new_file, 'w', encoding='UTF-8')
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')
in_file.close()
out_file.close()
# 使用示例
directory_path = r"D:\Personal\python\yolov5\data\labels\train" # 修改为你的目录路径
old_extension = ".xml" # 要修改的旧后缀名
new_extension = ".txt" # 新的后缀名
rename_file_extensions(directory_path, old_extension, new_extension)
开始训练
按如下建立目录结构
data/
├── images/
│ ├── train/
│ ├── val/
│ └── test/
├── labels/
│ ├── train/
│ ├── val/
│ └── test/
└── data.yaml
data.yaml内容按如下:
train: data/images/train # 修改为对应的目录
val: data/images/val # 修改为对应的目录
test: data/images/test # 修改为对应的test目录
# - images/test2007
nc: 1 # 标签的数量
# Classes
names: ['role'] # 修改为标签,所有标签都需要
运行开始训练
在clone的文件中,找到train.py文件;需要按如下进行修改,修改后运行:
def parse_opt(known=False):
parser = argparse.ArgumentParser()
parser.add_argument("--weights", type=str, default=ROOT / "yolov5s.pt", help="initial weights path") # 借用的模型
parser.add_argument("--cfg", type=str, default="", help="model.yaml path")
parser.add_argument("--data", type=str, default=ROOT / "data/data.yaml", help="dataset.yaml path") # 修改为刚刚定义的yaml文件
parser.add_argument("--hyp", type=str, default=ROOT / "data/hyps/hyp.scratch-low.yaml", help="hyperparameters path")
更多常见参数定义:
–img-size:输入图像的大小。
–batch-size:每批次的图像数量。
–epochs:训练轮数。
–data:数据配置文件路径。
–weights:预训练权重文件(可以使用 YOLOv5 提供的预训练模型)。
–cfg:模型配置文件路径。
–name:训练实验的名称,用于保存训练结果。
运行后测试:
使用自带的detect文件运行
使用前,需要进行一些修改:
def parse_opt():
parser = argparse.ArgumentParser()
# parser.add_argument("--weights", nargs="+", type=str, default=ROOT / "yolov5s.pt", help="model path or triton URL")
# 选择模型
parser.add_argument("--weights", nargs="+", type=str, default=r"D:\Personal\python\yolov5\runs\train\exp13\weights\last.pt", help="model path or triton URL")
# parser.add_argument("--source", type=str, default=ROOT / "data/images", help="file/dir/URL/glob/screen/0(webcam)")
# 要识别的文件
parser.add_argument("--source", type=str, default=r"D:\Personal\python\yolov5\data\images\test", help="file/dir/URL/glob/screen/0(webcam)")
# parser.add_argument("--data", type=str, default=ROOT / "data/coco128.yaml", help="(optional) dataset.yaml path")
parser.add_argument("--data", type=str, default="", help="(optional) dataset.yaml path")
parser.add_argument("--imgsz", "--img", "--img-size", nargs="+", type=int, default=[640], help="inference size h,w")
parser.add_argument("--conf-thres", type=float, default=0.25, help="confidence threshold")
parser.add_argument("--iou-thres", type=float, default=0.45, help="NMS IoU threshold")
parser.add_argument("--max-det", type=int, default=1000, help="maximum detections per image")
更多常用参数:
–weights:指定训练好的模型权重文件的路径。
–img-size:指定输入图像的大小(例如 640 表示 640x640 像素)。可以根据模型的要求调整此值。
–conf-thres:设置置信度阈值(例如 0.25)。低于此值的检测框会被过滤掉。
–iou-thres:设置 IOU 阈值(例如 0.45)。用于非极大值抑制,去除重复的检测框。
–source:指定测试图像的路径(如 path/to/your/image.jpg)。可以是单个图像文件、视频文件、文件夹路径或摄像头输入。
–save-txt:将检测结果保存为文本文件(可选)。
–save-conf:保存检测结果中的置信度分数(可选)。
–project:指定输出结果保存的文件夹路径(可选)。
–name:指定输出结果的文件夹名称(可选)。
如何使用
import yolov5
def function1(model_path, file_path):
# 可用,但是没有显示标记的框
# 加载模型
model = yolov5.load(model_path)
# 推理
results = model.forward(file_path)
# # 显示结果
detections = results.pandas().xyxy[0]
# 打印结果
print(detections)
results.show()
return results
model_path = "模型路径"
file_path = "图片路径"
"""
results.pandas().xyxy[0] 返回一个 Pandas DataFrame,包含以下列:
xmin:检测框左上角的 x 坐标
ymin:检测框左上角的 y 坐标
xmax:检测框右下角的 x 坐标
ymax:检测框右下角的 y 坐标
confidence:检测框的置信度分数
class:检测框对应的对象类别标签
name:检测框对应的对象类别名称
"""