yolov5物体识别
环境配置
Windows或Linux系统
良好的外网访问环境
任意Python编辑器(本文以Pycharm为例演示)
提示:AMD显卡的ROCm仅支持Linux
Windows环境下需要安装 Visual Studio
说明:此文章不传授和提供外网访问的教程和工具
CUDA环境配置
适用于Nvidia显卡,AMD请使用ROCm或者跳过此步骤,使用CPU
使用Nvidia app更新Nvidia驱动至最新版本
前往Nvidia官网下载并安装CUDA Toolkit
yolo环境配置
打开pycharm
点击 从 VCS 获取
输入yolo官方仓库地址https://github.com/ultralytics/yolov5
然后点击克隆
安装依赖
如果是 Nvidia用户 或AMD使用 ROCm 的用户,请先打开requirements.txt
文件,注释掉 torch 和 torchvision
其他用户请直接安装环境
打开终端
输入并回车,安装cuda版本pytorch
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu124
其他环境安装
然后终端再次输入
pip install -r requirements.txt
训练
标记
请先准备好用于训练的图片数据,也可以是视频数据
根据情况下载X-AnyLabeling
打开 X-AnyLabeling
点击右上角 文件 选项,打开图片所在的文件夹,或者打开视频
X-AnyLabeling 有个小bug,要点击两次才能选择文件
然后按 R 可以进行矩形框选标注
标注完成后,新建一个 classes.txt 文件,并填入所有标记的名称,一行一个,如图
然后回到 X-AnyLabeling ,点击 导出 ,选择 导出yolo标签
选则刚刚创建的 classes.txt 文件
这是你会发现你文件同级目录下出现一个 labels 目录,找不到可以观察导出文件时出现的弹窗
数据准备与训练
然后将资源按如下结构存放
├─images
│ ├─train
| | ├─ 001.jpg #用于训练的图片
| | ├─ 002.jpg
| | └─ ......
│ └─val
└─labels
├─train
| ├─ 001.txt #导出的标记数据
| ├─ 002.txt
| └─ ......
└─val
说明: val是在训练中用于检测的数据,和train是一样的结构,不知道如何操作可以把train中的资源复制到val中
然后编写dataset.yaml
# 这里的路径是相对与运行目录(一般为train.py程序)的路径,如不清楚如何填写,建议填写绝对路径,参考如下:
# train: C:/Users/your_username/PycharmProjects/yolov5/source/images/train
# val: C:/Users/your_username/PycharmProjects/yolov5/source/images/val
train: ./source/images/train
val: ./source/images/val
# nc为种类数量
nc: 1
# 名称,classes.txt,X-AnyLabeling中的群组编号顺序对应
names:
0: 'A meng'
# 1: 'other'
# 2: ......
然后pycharm打开终端,输入
python train.py --img 640 --data source/dataset.yaml --cfg yolov5s.yaml --weights yolov5s.pt --epochs 100
epochs 参数代表训练轮数,理论上100轮足够,轮数过多会导致模型过拟合。
训练需要的是大量的 样本数据,而不是过多的训练轮数
查看结果
训练完成后会在runs/train/exp/weights
下面生成 best.pt 和 last.pt
best.pt可用于检测,last.pt可用于后续继续训练(替换上述python指令中的yolov5s.pt为你last.pt的路径)
强调: exp后面会跟随一些数字,数字越大越新,请使用你训练好的最终模型
检测
简单测试
使用官方的 detect.py 检测结果
python detect.py --weights runs/train/exp2/weights/best.pt --source source/images/val/001.jpg
检测后,会在runs/detect
下面生成exp目录,里面有检测结果的图片
程序中调用
可参考如下代码
传入opencv图片变量,返回中心点坐标和绘制的图片
import cv2
import time
import yolov5
class vegetable_detect:
class __results__:
def __init__(self):
self.name = []
self.x = []
self.y = []
self.confidence = []
self.image = None
def __init__(self, model_path):
'''
初始化YOLOv5检测器
:param model_path: YOLOv5模型文件路径
'''
self.model = yolov5.load(model_path)
self.is_detecting = False
def detect(self, image):
'''
检测图像中的物体
:param image: 输入图像
:return: 结果类结构
result.name: 物体名称列表
result.x: 物体中心点x坐标列表
result.y: 物体中心点y坐标列表
result.confidence: 物体置信度列表
result.image: 检测后的图像
'''
while self.is_detecting:
time.sleep(0.5)
results = self.model(image, augment=True)
self.is_detecting = True
# 存储检测结果的列表
result = self.__results__()
# 遍历检测结果
try:
for *xyxy, conf, cls in results.xyxy[0]:
label = f'{self.model.model.names[int(cls)]} {conf:.2f}'
# 画出矩形框
cv2.rectangle(image, (int(xyxy[0]), int(xyxy[1])), (int(xyxy[2]), int(xyxy[3])), (0, 0, 255), 2)
cv2.putText(image, label, (int(xyxy[0]), int(xyxy[1]) - 10), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2)
# 计算中心点坐标
center_x = int((xyxy[0] + xyxy[2]) / 2)
center_y = int((xyxy[1] + xyxy[3]) / 2)
# 画出中心点
cv2.circle(image, (center_x, center_y), 5, (255, 0, 0), -1)
# 存储中心点坐标,物体名称,置信度和图像
result.name.append(self.model.model.names[int(cls)])
result.x.append(center_x)
result.y.append(center_y)
result.confidence.append(float(conf))
result.image = image
except Exception as e:
print("未检测到物体:", e)
self.is_detecting = False
return result
# 使用示例
if __name__ == "__main__":
# 加载自定义训练的YOLOv5模型
model_path = 'runs/train/exp2/weights/best.pt'
detector = vegetable_detect(model_path)
# 加载图像
imgPath = 'source/images/val/test2.jpg'
img = cv2.imread(imgPath)
# 检测物体
results = detector.detect(img)
# 打印所有中心点的坐标、物体名称和置信度
print("识别结果:")
for i in range(len(results.x)):
print(f"物体名称:{results.name[i]} 中心点坐标:({results.x[i]}, {results.y[i]}) 置信度:{results.confidence[i]:.2f}")
# 显示结果图像
cv2.imshow('YOLOv5 Real-time Object Detection', results.image)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果如下
问题与解决
- NotImplementedError: cannot instantiate ‘WindowsPath‘ on your system
在用到 yolov5 库的源码前加入如下代码
import platform
import pathlib
plt = platform.system()
if plt != 'Windows':
pathlib.WindowsPath = pathlib.PosixPath