yolo,一个基于torch框架开发的ai图像识别算法,可以很快识别的同时有一定的准确率而大受关注,本文以dnf游戏脚本为应用场景,结合yolo实现dnf自动刷图功能来讲解yolo的使用方法。大体思路就是使用yolo识别出人物,怪,传送门,掉落物品后,通过键盘事件,鼠标事件等技术实现自动化操作。
强调,本文只是以此为应用场景,不会用于商用,因此只会提供部分代码。
开始之前,先看下效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kvj7iJFb-1689036092231)(C:\Users\honor\Desktop\yolo\final.gif)]
有没有被惊艳到,好了,下面开始讲解yolo的使用
python环境如果没有的话,大家自己去网上搜一下,很简单
安装pytorch:去官网https://pytorch.org/get-started/locally/ 选择适合自己的python包(学习使用cpu即可,应用的话建议搭建GPU环境,训练模型会快很多)
安装yolo8:pip install ultralytics --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple
安装其他yolov8使用的工具包:pip install numpy opencv-python pillow pandas matplotlib seaborn tqdm wandb seedir emoji -i https://pypi.tuna.tsinghua.edu.cn/simple
安装好后在python项目中执行以下代码可以查看是否安装成功
import ultralytics
ultralytics.checks()
成功后控制台打印:
Ultralytics YOLOv8.0.126 Python-3.10.3 torch-2.0.1+cpu CPU
Setup complete (16 CPUs, 39.4 GB RAM, 215.8/275.7 GB disk)
yolov8(8改名叫ultralytics了)的github上有预训练模型的python代码,我们可以直接拿来用
from ultralytics import YOLO
# 加载模型
model = YOLO("yolov8.yaml") # 从头开始构建新模型 官网的8n没找到,我就用了8
model = YOLO("yolov8n.pt") # 加载预训练模型(建议用于训练)
# 使用模型
model.train(data="coco128.yaml", epochs=3) # 训练模型
metrics = model.val() # 在验证集上评估模型性能
results = model("https://ultralytics.com/images/bus.jpg") # 对图像进行预测
# success = model.export(format="onnx") # 将模型导出为 ONNX 格式
以上所有文件都可以在ultralytics的github上找到,就不一一介绍怎么下载了, yolov8n.yaml 和 yolov8n.pt是模型的两种表现形式,训练的时候我们任选一种就好,如果是自己训练建议选择xx.yaml形式,因为xx.pt形式怎么训练我也不知道。
模型导出代码暂时注掉,其实就是导出成一种通用的模型格式,暂时用不到。
下面重点说明一下yolov8n.yaml和coco128.yaml里面各个配置的作用,不理解不要紧,先混个脸熟,下面自己训练模型的时候就会理解
yolov8.yaml
# Ultralytics YOLO , AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect
# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
# [depth, width, max_channels]
n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPs
s: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPs
m: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPs
l: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
x: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs
# YOLOv8.0n backbone
backbone:
# [from, repeats, module, args]
- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
- [-1, 3, C2f, [128, True]]
- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
- [-1, 6, C2f, [256, True]]
- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16
- [-1, 6, C2f, [512, True]]
- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32
- [-1, 3, C2f, [1024, True]]
- [-1, 1, SPPF, [1024, 5]] # 9
# YOLOv8.0n head
head:
- [-1, 1, nn.Upsample, [None, 2, 'nearest']]
- [[-1, 6], 1, Concat, [1]] # cat backbone P4
- [-1, 3, C2f, [512]] # 12
- [-1, 1, nn.Upsample, [None, 2, 'nearest']]
- [[-1, 4], 1, Concat, [1]] # cat backbone P3
- [-1, 3, C2f, [256]] # 15 (P3/8-small)
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 12], 1, Concat, [1]] # cat head P4
- [-1, 3, C2f, [512]] # 18 (P4/16-medium)
- [-1, 1, Conv, [512, 3, 2]]
- [[-1, 9], 1, Concat, [1]] # cat head P5
- [-1, 3, C2f, [1024]] # 21 (P5/32-large)
- [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)
nc:表示模型有多少种要识别的类别(比dnf的yaml有怪物,人物,物品,可进入门,不可进入门五种,那么nc就标注5)
剩下内容是卷积神经网络相关的内容,自己训练时不需要修改,原样cv即可
coco128.yaml 这个是重点,自己训练的时候要修改为自己对应的内容,为了方便解释,我直接在属性后面加了注释
# Ultralytics YOLO , AGPL-3.0 license
# COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 mine_images from COCO train2017) by Ultralytics
# Example usage: yolo train data=coco128.yaml
# parent
# ├── ultralytics
# └── 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 相对于datasets文件夹 数据集放在哪里 。。/是父级目录 。/是当前目录
train: images/train2017 # train mine_images (relative to 'path') 128 mine_images 相对于path目录下训练集的路径
val: images/val2017 # val mine_images (relative to 'path') 128 mine_images 相对于path目录下验证集的路径 这里不区分验证和测试集 所以把不用于训练只用于评估的用一种就可以了
test: # test mine_images (optional)
# Classes 框的类别,即yolov8.yaml中nc具体有哪些
names:
0: person
1: bicycle
2: car
3: motorcycle
4: airplane
5: bus
6: train
7: truck
8: boat
9: traffic light
10: fire hydrant
11: stop sign
12: parking meter
13: bench
14: bird
15: cat
16: dog
17: horse
18: sheep
19: cow
20: elephant
21: bear
22: zebra
23: giraffe
24: backpack
25: umbrella
26: handbag
27: tie
28: suitcase
29: frisbee
30: skis
31: snowboard
32: sports ball
33: kite
34: baseball bat
35: baseball glove
36: skateboard
37: surfboard
38: tennis racket
39: bottle
40: wine glass
41: cup
42: fork
43: knife
44: spoon
45: bowl
46: banana
47: apple
48: sandwich
49: orange
50: broccoli
51: carrot
52: hot dog
53: pizza
54: donut
55: cake
56: chair
57: couch
58: potted plant
59: bed
60: dining table
61: toilet
62: tv
63: laptop
64: mouse
65: remote
66: keyboard
67: cell phone
68: microwave
69: oven
70: toaster
71: sink
72: refrigerator
73: book
74: clock
75: vase
76: scissors
77: teddy bear
78: hair drier
79: toothbrush
# Download script/URL (optional)
download: https://ultralytics.com/assets/coco128.zip(下载训练集的地址)
执行官方提供的预模型训练方法,等待训练结束。我们会看到当前项目目录中多了几个目录
datasets文件夹下即 coco128.yaml 最后一行下载的内容,也是yolo模型具体要训练的训练集,将来我们自己训练模型,也是要给yolo提供同样的内容。
images文件夹下是图片,labels文件夹下是txt文件,图片和txt文件一一对应
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IlLPEADh-1689036092232)(C:\Users\honor\Desktop\yolo\1688908243790.png)]
这是图片:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WjYkIJ7H-1689036092232)(C:\Users\honor\Desktop\yolo\000000000009.jpg)]
这是图片对应的txt文件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lln8ohuM-1689036092233)(C:\Users\honor\Desktop\yolo\1688908664055.png)]
大家乍一看可能有点懵,这个txt文件里面是什么呢。下面给大家看一个这个图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IqQDZQdK-1689036092233)(C:\Users\honor\Desktop\yolo\1688908809326.png)]
聪明的小伙伴应该已经看出端倪了,没错,txt中存放的就是标注信息,这些标注信息和图片结合使用,提供给模型去学习。
txt文件中每一行代表了一个框,从左到右依次代表:框的类别(coco128.yaml文件中names编号),框的中心点x坐标百分比,框的中心点y坐标百分比,框的宽度百分比,框的高度百分比。
后面我们训练自己的模型时,就是要通过labelme软件,拿到图片以及框的txt信息,这个放在后面训练自己模型的时候再具体说
训练完成后还多了一个run文件夹(默认project和name情况下),best.pt和last.pt就是我们训练后得到的模型,best是最好的模型,last是最后的模型,建议选择best
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qCyvQlYy-1689036092233)(C:\Users\honor\Desktop\yolo\1688909416587.png)]
得到预训练模型后我们就可以去处理图片了,results = model(img_path),result就是处理的结果,结果各个字段的意思我已经写在代码里了,同时我使用结果处理了图片,以方便观察处理结果
import numpy
from ultralytics import YOLO
import cv2
import matplotlib.pyplot as plt
import tensorflow as tf
import torch
# -----------------识别出来,并以图片框展示出来结果-----------------
# 有 GPU 就用 GPU,没有就用 CPU
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
print('device:', device)
# 载入预训练模型 这里使用图象检测
# model = YOLO('models/yolov8x-pose-p6.pt')
model = YOLO("demo_project/demo_name/weights/best.pt")
# 切换计算设备
model.to(device)
print(model.device)
print(model.names)
img_path = "mine_assets/mine_images/45.jpg"
results = model(img_path)
# -----------解析预测结果-----------
print("len(results):", len(results))
print("预测结果:", results[0])
# 预测框的所有类别(MS COCO数据集八十类)
print(results[0].names)
# 预测类别 ID
print("预测类别 ID", results[0].boxes.cls)
num_bbox = len(results[0].boxes.cls)
print('预测出 {} 个框'.format(num_bbox))
# 每个框的置信度
print('每个框的置信度:{}'.format(results[0].boxes.conf))
# 每个框的:左上角XY坐标、右下角XY坐标
print('每个框的:左上角XY坐标、右下角XY坐标:{}'.format(results[0].boxes.xyxy))
# 转成整数的 numpy array
bboxes_xyxy = results[0].boxes.xyxy.cpu().numpy().astype('uint32')
print('转成整数的每个框的:左上角XY坐标、右下角XY坐标:{}'.format(bboxes_xyxy))
# -----------OpenCV可视化处理结果-----------
img_bgr = cv2.imread(img_path)
plt.imshow(img_bgr[:, :, ::-1])
plt.show()
# 框(rectangle)可视化配置
bbox_color = (150, 0, 0) # 框的 BGR 颜色
bbox_thickness = 6 # 框的线宽
# 框类别文字
bbox_labelstr = {
'font_size': 1, # 字体大小
'font_thickness': 2, # 字体粗细
'offset_x': 0, # X 方向,文字偏移距离,向右为正
'offset_y': -10, # Y 方向,文字偏移距离,向下为正
}
for idx in range(num_bbox): # 遍历每个框
# 获取该框坐标
bbox_xyxy = bboxes_xyxy[idx]
# 获取框的预测类别(对于关键点检测,只有一个类别)
# bbox_label = results[0].names[0]
# 修改代码
proto = tf.make_tensor_proto(results[0].boxes.cls)
array = tf.make_ndarray(proto)
bbox_label = results[0].names[array[idx]]
# 画框
img_bgr = cv2.rectangle(img_bgr, (bbox_xyxy[0], bbox_xyxy[1]), (bbox_xyxy[2], bbox_xyxy[3]), bbox_color,
bbox_thickness)
# 写框类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细
img_bgr = cv2.putText(img_bgr, bbox_label,
(bbox_xyxy[0] + bbox_labelstr['offset_x'], bbox_xyxy[1] + bbox_labelstr['offset_y']),
cv2.FONT_HERSHEY_SIMPLEX, bbox_labelstr['font_size'], bbox_color,
bbox_labelstr['font_thickness'])
# 展示处理结果
plt.imshow(img_bgr[:, :, ::-1])
plt.show()
cv2.imwrite('mine_assets/mine_result/result.jpg', img_bgr)
这是效果,还是蛮不错的:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZzSN0a4H-1689036092233)(C:\Users\honor\Desktop\yolo\1bd7424b4f67d04ec0701a37080ec48.png)]
初学的时候看ultralytics的官网会有很多专业名词不知道什么意思,不知道该怎么选择,因此我把我学习时遇到的不懂的名词做了个记录整理
mAP值
综合衡量检测效果,mAP值越大效果越好
根据精度p 召回率r得来
IOU
iou=真实值与预测值的交集/真实值与预测值的并集
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-01Xewmhn-1689036092234)(C:\Users\honor\Desktop\yolo\1688631851186.png)]
精度(Precision)和召回率(Recall)
Precision = TP/TP+FP
Recall = TP/TP+FN
例:
已知条件:一个班级100人,80男,20女
目标:找出所有女生
结果:找出了50人,19女,31男
TP=19 FP=31 TN=49 FN=1
预模型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CBWdNYEt-1689036092234)(C:\Users\honor\AppData\Roaming\Typora\typora-user-images\1688691398108.png)]
n->s->…->x 模型由小到大
size:训练图象的尺寸
mAP:综合衡量检测效果
speed:不同硬件上的推理速度
params:参数量(百万),神经元的权重
FLOPs:神经网络的浮点运算量,输入一张图片,跑一个前项运算,需要多少次运算,越少越快
引用: