使用配置:Win11 +RTX4060
Conda环境
Yolov8 环境选择 python 3.8
conda create -n yolov8 python=3.8
activate yolov8
(base) C:\Windows\System32>activate yolov8
(yolov8) C:\Windows\System32>pip install ultralytics
Installing collected packages: pytz, py-cpuinfo, mpmath, zipp, urllib3, tzdata, typing-extensions, sympy, six, pyyaml, pyparsing, psutil, pillow, packaging, numpy, networkx, MarkupSafe, kiwisolver, idna, fsspec, fonttools, filelock, cycler, colorama, charset-normalizer, certifi, tqdm, scipy, requests, python-dateutil, opencv-python, jinja2, importlib-resources, contourpy, torch, pandas, matplotlib, torchvision, thop, seaborn, ultralytics
Successfully installed MarkupSafe-2.1.5 certifi-2024.2.2 charset-normalizer-3.3.2 colorama-0.4.6 contourpy-1.1.1 cycler-0.12.1 filelock-3.13.4 fonttools-4.51.0 fsspec-2024.3.1 idna-3.6 importlib-resources-6.4.0 jinja2-3.1.3 kiwisolver-1.4.5 matplotlib-3.7.5 mpmath-1.3.0 networkx-3.1 numpy-1.24.4 opencv-python-4.9.0.80 packaging-24.0 pandas-2.0.3 pillow-10.3.0 psutil-5.9.8 py-cpuinfo-9.0.0 pyparsing-3.1.2 python-dateutil-2.9.0.post0 pytz-2024.1 pyyaml-6.0.1 requests-2.31.0 scipy-1.10.1 seaborn-0.13.2 six-1.16.0 sympy-1.12 thop-0.1.1.post2209072238 torch-2.2.2 torchvision-0.17.2 tqdm-4.66.2 typing-extensions-4.11.0 tzdata-2024.1 ultralytics-8.1.45 urllib3-2.2.1 zipp-3.18.1
检验模型下载情况
(yolov8) D:\>cd D:\pythonSpace\test_demo\ultralytics-main
(yolov8) D:\pythonSpace\test_demo\ultralytics-main>yolo predict model=yolov8n.pt source='https://ultralytics.com/images/bus.jpg'
Downloading https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8n.pt to 'yolov8n.pt'...
100%|█████████████████████████████████████████████████████████████████████████████| 6.23M/6.23M [04:35<00:00, 23.7kB/s]
Ultralytics YOLOv8.1.45 🚀 Python-3.8.19 torch-2.2.2+cpu CPU (13th Gen Intel Core(TM) i7-13700F)
YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs
Downloading https://ultralytics.com/images/bus.jpg to 'bus.jpg'...
100%|████████████████████████████████████████████████████████████████████████████████| 476k/476k [00:01<00:00, 373kB/s]
image 1/1 D:\pythonSpace\test_demo\ultralytics-main\bus.jpg: 640x480 4 persons, 1 bus, 1 stop sign, 44.9ms
Speed: 2.4ms preprocess, 44.9ms inference, 663.4ms postprocess per image at shape (1, 3, 640, 480)
Results saved to runs\detect\predict
💡 Learn more at https://docs.ultralytics.com/modes/predict
Pytorch和CUDA
(base) C:\Windows\System32>activate yolov8
(yolov8) C:\Windows\System32>conda search cudatoolkit
Loading channels: done
# Name Version Build Channel
cudatoolkit 8.0 4 pkgs/main
cudatoolkit 9.0 1 pkgs/main
cudatoolkit 9.2 0 pkgs/main
cudatoolkit 10.0.130 0 pkgs/main
cudatoolkit 10.1.168 0 pkgs/main
cudatoolkit 10.1.243 h74a9793_0 pkgs/main
cudatoolkit 10.2.89 h74a9793_0 pkgs/main
cudatoolkit 10.2.89 h74a9793_1 pkgs/main
cudatoolkit 11.0.221 h74a9793_0 pkgs/main
cudatoolkit 11.3.1 h59b6b97_2 pkgs/main
cudatoolkit 11.8.0 hd77b12b_0 pkgs/main
(yolov8) C:\Windows\System32>conda search cudnn
Loading channels: done
# Name Version Build Channel
cudnn 7.1.4 cuda8.0_0 pkgs/main
cudnn 7.1.4 cuda9.0_0 pkgs/main
cudnn 7.3.1 cuda10.0_0 pkgs/main
cudnn 7.3.1 cuda9.0_0 pkgs/main
cudnn 7.6.0 cuda10.0_0 pkgs/main
cudnn 7.6.0 cuda10.1_0 pkgs/main
cudnn 7.6.0 cuda9.0_0 pkgs/main
cudnn 7.6.4 cuda10.0_0 pkgs/main
cudnn 7.6.4 cuda10.1_0 pkgs/main
cudnn 7.6.4 cuda9.0_0 pkgs/main
cudnn 7.6.5 cuda10.0_0 pkgs/main
cudnn 7.6.5 cuda10.1_0 pkgs/main
cudnn 7.6.5 cuda10.2_0 pkgs/main
cudnn 7.6.5 cuda9.0_0 pkgs/main
cudnn 7.6.5 cuda9.2_0 pkgs/main
cudnn 8.2.1 cuda11.3_0 pkgs/main
cudnn 8.9.2.26 cuda11_0 pkgs/main
(yolov8) C:\Windows\System32>conda install cudatoolkit=11.3.1
Collecting package metadata (current_repodata.json): done
Solving environment: done
==> WARNING: A newer version of conda exists. <==
current version: 23.7.4
latest version: 24.3.0
Please update conda by running
$ conda update -n base -c defaults conda
Or to minimize the number of packages updated during conda update use
conda install conda=24.3.0
## Package Plan ##
environment location: D:\Anaconda3\envs\yolov8
added / updated specs:
- cudatoolkit=11.3.1
The following packages will be downloaded:
package | build
---------------------------|-----------------
cudatoolkit-11.3.1 | h59b6b97_2 545.3 MB defaults
------------------------------------------------------------
Total: 545.3 MB
The following NEW packages will be INSTALLED:
cudatoolkit pkgs/main/win-64::cudatoolkit-11.3.1-h59b6b97_2
The following packages will be UPDATED:
ca-certificates anaconda/cloud/conda-forge::ca-certif~ --> pkgs/main::ca-certificates-2024.3.11-haa95532_0
Proceed ([y]/n)? y
Downloading and Extracting Packages
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
(yolov8) C:\Windows\System32>conda install cudnn=8.2.1
Collecting package metadata (current_repodata.json): done
Solving environment: done
==> WARNING: A newer version of conda exists. <==
current version: 23.7.4
latest version: 24.3.0
Please update conda by running
$ conda update -n base -c defaults conda
Or to minimize the number of packages updated during conda update use
conda install conda=24.3.0
## Package Plan ##
environment location: D:\Anaconda3\envs\yolov8
added / updated specs:
- cudnn=8.2.1
The following packages will be downloaded:
package | build
---------------------------|-----------------
cudnn-8.2.1 | cuda11.3_0 428.9 MB defaults
------------------------------------------------------------
Total: 428.9 MB
The following NEW packages will be INSTALLED:
cudnn pkgs/main/win-64::cudnn-8.2.1-cuda11.3_0
Proceed ([y]/n)? y
Downloading and Extracting Packages
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
安装 pytorch 1.12.1
(1)方法一
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=11.3 -c pytorch
(2)方法二
download.pytorch.org/whl/torch_stable.html#
输入d:(先换盘符,因为我把文件下载在D盘了)
输入:cd D:\Download\(该处为指定目录XXX,即刚才whl文件的保存地址)
输入pip install torch-1.12.1 可以按Tab键自动补全,
然后pip install torchvision-0.13.1+cu113-cp38-cp38-win_amd64,
最后pip install torchaudio-0.12.1+cu113-cp38-cp38-win_amd64,
测试 pytorch是否安装成功,
虚拟环境(yolov8)下进入python:输入 python
依次执行以下语句:
import torch
import torchvision
print(torch.cuda.is_available())
安装 ultralytics(yolov8)
pip install ultralytics
使用Pip在一个[**Python>=3.8**](https://www.python.org/)环境中安装`ultralytics`包,此环境还需包含[**PyTorch>=1.8**](https://pytorch.org/get-started/locally/)。这也会安装所有必要的[依赖项](https://github.com/ultralytics/ultralytics/blob/main/pyproject.toml)。
数据格式
YOLO数据集的格式主要包括以下几部分:
- 图像文件: 这是数据集中的图像文件,通常是jpg或png格式。
- 标注文件: 这是一个文本文件,包含了每张图像中目标对象的类别和位置信息。
- 类别文件: 这是一个文本文件,包含了数据集中所有目标对象的类别信息。
Yolov8数据集标注文件为txt格式。
xml转换txt
import os, shutil
from tqdm import tqdm
from collections import Counter
import xml.etree.ElementTree as ET
from PIL import Image
import yaml
import random
class Dataset_Transforme_Yolov8:
def __init__(self, jpg_path: str, xml_path: str, save_path: str, divide=False):
self.jpg_path = jpg_path
self.xml_path = xml_path
self.save_path = save_path
self.divide = divide
def get_classes(self):
'''
统计路径下xml里的各类别标签数量
'''
names = []
files_1 = []
for root, dirs, files in os.walk(self.xml_path):
for file in files:
if ".xml" in file:
file = os.path.join(root, file)
subs = ET.parse(file).getroot().findall("object")
if len(subs) != 0:
files_1.append(file)
for sub in subs:
name = sub.find("name").text
names.append(name)
result = Counter(names)
return result, files_1
def xml2txt(self, classes, file_path, txt_save_path, image_width, image_height):
'''
根据xml文件生成txt标签文件
:param classes:类别列表
:param file_path:xml文件路径
:param image_width:图片宽度
:param image_height:图片高度
'''
tree = ET.parse(file_path)
root = tree.getroot()
objects = root.findall('object')
bboxes = []
class_names = []
for obj in objects:
bbox = obj.find('bndbox')
xmin = int(bbox.find('xmin').text)
ymin = int(bbox.find('ymin').text)
xmax = int(bbox.find('xmax').text)
ymax = int(bbox.find('ymax').text)
class_name = obj.find('name').text
c1 = round((xmin + xmax) / (image_width * 2), 6)
c2 = round((ymin + ymax) / (image_height * 2), 6)
c3 = round((xmax - xmin) / image_width, 6)
c4 = round((ymax - ymin) / image_height, 6)
if class_name in classes:
# print(class_name)
bboxes.append([c1, c2, c3, c4])
class_names.append(class_name)
# 将数据写入到YOLO的TXT文件中
with open(txt_save_path, 'w') as file:
for bbox, class_name in zip(bboxes, class_names):
file.write(
f"{classes.index(class_name)} {bbox[0]} {bbox[1]} {bbox[2]} {bbox[3]}\n")
def data_split(self, full_list, train, val, shuffle, seed):
"""
数据集拆分: 将列表full_list按比例划分为3个子列表
:param full_list: 数据列表
:param ratio: 比例
:param shuffle: 是否打乱顺序
:param seed: 随机种子
:return:
"""
n_total = len(full_list)
offset_train = int(n_total * train)
offset_val = int(n_total * val)
offset_trainval = offset_train + offset_val
if n_total == 0 or offset_train < 1 or train + val > 1.0:
raise ValueError("划分出错,请检查列表与划分比例!参考格式train,val->0.7,0.1")
if shuffle:
random.seed(seed)
random.shuffle(full_list)
train_list = full_list[:offset_train]
val_list = full_list[offset_train:offset_trainval]
test_list = full_list[offset_trainval:]
return train_list, val_list, test_list
def voc2yolov8(self, train, val, shuffle=True, seed=10):
"""
:param train: 训练集比例
:param val: 验证集比例
"""
obj_classes, files = self.get_classes()
os.makedirs(os.path.join(self.save_path, "images/train"), exist_ok=True)
os.makedirs(os.path.join(self.save_path, "images/val"), exist_ok=True)
os.makedirs(os.path.join(self.save_path, "images/test"), exist_ok=True)
os.makedirs(os.path.join(self.save_path, "labels/train"), exist_ok=True)
os.makedirs(os.path.join(self.save_path, "labels/val"), exist_ok=True)
os.makedirs(os.path.join(self.save_path, "labels/test"), exist_ok=True)
classes = list(obj_classes.keys())
train_list, val_list, test_list = self.data_split(files, train, val, shuffle, seed)
for file in tqdm(files):
if ".xml" in file:
# name = file.replace("\\", "/").split("/")[-1].split(".")[0]
name = os.path.splitext(os.path.basename(file))[0]
xml_file = file.replace("\\", "/")
jpg_file = os.path.join(self.jpg_path, name + ".jpg").replace("\\", "/")
img_w, img_h = Image.open(jpg_file).size
if file in val_list:
txt_save_path = os.path.join(self.save_path, "labels/val", name + ".txt")
self.xml2txt(classes, xml_file, txt_save_path, img_w, img_h)
elif file in test_list:
txt_save_path = os.path.join(self.save_path, "labels/test", name + ".txt")
self.xml2txt(classes, xml_file, txt_save_path, img_w, img_h)
else:
txt_save_path = os.path.join(self.save_path, "labels/train", name + ".txt")
self.xml2txt(classes, xml_file, txt_save_path, img_w, img_h)
if self.divide:
if file in val_list:
shutil.copy(jpg_file, os.path.join(self.save_path, "images/val", name + ".jpg"))
elif file in test_list:
shutil.copy(jpg_file, os.path.join(self.save_path, "images/test", name + ".jpg"))
else:
shutil.copy(jpg_file, os.path.join(self.save_path, "images/train", name + ".jpg"))
# 编写yaml文件
classes_txt = {i: classes[i] for i in range(len(classes))} # 标签类别
data = {
'path': os.path.join(os.getcwd(), self.save_path),
'train': "images/train",
'val': "images/val",
'test': "images/test",
'names': classes_txt,
'download': ''
}
with open(self.save_path + '/dataset.yaml', 'w', encoding="utf-8") as file:
yaml.dump(data, file, allow_unicode=True)
print("标签:", dict(obj_classes))
print("有标签文件数量:", len(files))
if __name__ == '__main__':
jpg_path = r"D:\pythonSpace\test_demo\ultralytics-main\data\mydata04\image" # 你的图片路径
xml_path = r"D:\pythonSpace\test_demo\ultralytics-main\data\mydata04\xml" # 你的xml路径
save_path = r"D:\pythonSpace\test_demo\ultralytics-main\data\mydata04" # 保存数据路径
deals = Dataset_Transforme_Yolov8(jpg_path, xml_path, save_path, divide=True)
deals.voc2yolov8(0.7, 0.1) # 训练集与验证集占比
训练
新建train.py
import multiprocessing
# 定义其他函数和类
def main():
from ultralytics import YOLO
import torch
# 检查CUDA是否可用,如果可用则选择GPU,否则选择CPU
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 加载模型,并将模型移动到选定的设备上
model = YOLO("yolov8s.yaml").to(device)
# 指定数据集路径
data = "D:\\pythonSpace\\test_demo\\ultralytics-main\\data\\mydata03\\dataset.yaml"
# 开始训练,确保训练在选定的设备上执行
model.train(data=data, epochs=300, batch=16, device=device,amp=False)
# 主程序逻辑
# 在这里调用你的模型训练代码等等
if __name__ == '__main__':
multiprocessing.freeze_support() # 添加这一行来确保在 Windows 平台上正确运行多进程
main()
预测媒体
新建run.py
from ultralytics import YOLO
model = YOLO("runs/detect/train3/weights/best.pt")
# 或者(用于训练): model = YOLO("yolov8x.yaml")
image = "data/mydata/image" # 或者图片文件夹/视频文件
model.predict(image, save=True) # 返回image的预测结果
# 训练:model.train(data="数据集路径.yaml", epochs=200, batch=16)
# 训练数据集类型看yolov8训练流程
预测视频帧
新建detect.py
from ultralytics import YOLO
from collections import defaultdict
import cv2
model = YOLO("runs/detect/train4/weights/last.pt")
video_path = "D:\\Desktop\\bb1.mp4"
# 打开视频文件
cap = cv2.VideoCapture(video_path)
frame_rate_divider = 5 # 设置帧率除数
frame_count = 0 # 初始化帧计数器
counts = defaultdict(int)
object_str = ""
index = 0
while cap.isOpened(): # 检查视频文件是否成功打开
ret, frame = cap.read() # 读取视频文件中的下一帧,ret 是一个布尔值,如果读取帧成功
if not ret:
break
# 每隔 frame_rate_divider 帧进行一次预测
if frame_count % frame_rate_divider == 0:
results = model(frame)
key = f"({index}): "
index = index + 1
for result in results:
for box in result.boxes:
class_id = result.names[box.cls[0].item()]
counts[class_id] += 1
object_str = object_str + ". " + key
for class_id, count in counts.items():
object_str = object_str + f"{count} {class_id},"
counts = defaultdict(int)
frame_count += 1 # 更新帧计数器
object_str = object_str.strip(',').strip('.')
print("reuslt:", object_str)
cap.release()
cv2.destroyAllWindows()
获取不同形式输出:
- txt 放在print之前
with open('output.txt', 'w') as f:
f.write("result: " + object_str + "\n")
- 保存csv/json
import csv
with open('detection_results.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['Frame Number', 'Class ID', 'Count'])
for frame_key, results in frame_results.items(): # assuming there's a dictionary with frame results
for result in results:
writer.writerow([frame_key, result['class_id'], result['count']])