init
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/datasets
|
||||||
|
/weights
|
141
README.MD
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# 训练自己的YOLOv8模型
|
||||||
|
|
||||||
|
## 准备数据集
|
||||||
|
|
||||||
|
### 安装 LabelImg
|
||||||
|
|
||||||
|
在命令提示符中输入以下命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
```
|
||||||
|
|
||||||
|
等待安装完成
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
运行
|
||||||
|
|
||||||
|
```bash
|
||||||
|
labelimg
|
||||||
|
```
|
||||||
|
|
||||||
|
启动之后界面长这样
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
设置自动保存
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
labelimg的常用快捷键(熟练使用快捷键,提高效率)
|
||||||
|
|
||||||
|
| 快捷键 | 功能 |
|
||||||
|
| :--- | :----: |
|
||||||
|
| W | 画框(创建或编辑标签框) |
|
||||||
|
| D |切换到下一张图片 |
|
||||||
|
| A |切换到上一张图片 |
|
||||||
|
| CTRL+Q | 退出LabelImg |
|
||||||
|
| CTRL+S |保存当前图片的标签 |
|
||||||
|
| Delete | 删除当前选中的标签框 |
|
||||||
|
|
||||||
|
### 开始标注
|
||||||
|
|
||||||
|
- 点击Open Dir 选择原图片所在文件夹
|
||||||
|
|
||||||
|
- 点击Change Save Dir 选择存储位置
|
||||||
|
|
||||||
|
- 使用快捷键,开始标注,左侧将格式设置成yolo
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 将标注好的数据集按照指定路径放置
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 训练YOLOv8模型
|
||||||
|
|
||||||
|
- 由于本地安装cuda较为麻烦,这里不做介绍,本文将使用腾讯云算力平台
|
||||||
|
|
||||||
|
### 登录并进入腾讯云高性能应用服务 HAI
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 创建实例
|
||||||
|
|
||||||
|
- 可选用预装了cuda的Pytorch,算力方案越贵,训练速度越快,普通1.2元/时的也够用了。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 创建实例之后,选择CloudStudio进入后台
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 在终端安装yolo环境,克隆训练程序,上传数据集
|
||||||
|
|
||||||
|
- 使用国内服务器时候可使用清华源加速
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
```
|
||||||
|
|
||||||
|
- 使用国外服务器时候可直接
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install ultralytics
|
||||||
|
```
|
||||||
|
|
||||||
|
- 安装libGL.so.1 库
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install libgl1-mesa-glx
|
||||||
|
```
|
||||||
|
|
||||||
|
- 环境安装完成后,克隆此训练代码
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone http://gitea.qutcmrt.top/Robofish/YOLOv8.git
|
||||||
|
```
|
||||||
|
|
||||||
|
- 上传刚刚准备好的数据集datasets
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 修改yolo.yaml的内容,直接复制绝对路径。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 开始训练
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yolo train data=yolo.yaml model=yolov8n.pt epochs=300 imgsz=640 batch=8 workers=0 device=0
|
||||||
|
```
|
||||||
|
|
||||||
|
- 其中 data=YOLO.yaml 修改为实际yaml路径,model=yolov8n.pt修改为模型路径(按照教程走不用修改)
|
||||||
|
- 如果使用cpu训练,修改device='cpu',如果想使用多卡训练,device='\0,1,2,xxx\'
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 结束训练
|
||||||
|
|
||||||
|
- 训练完成的模型将位于 ' runs\detect\train\weights '
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 右键下载,即可将训练好的模型下载到本地。
|
||||||
|
|
||||||
|
## 测试模型
|
||||||
|
|
||||||
|
- 在安装了ultralytics的电脑中,运行scripts文件夹中的track_test.py,修改模型和摄像头。
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### LabelImg无法标注,闪退
|
||||||
|
|
||||||
|
- 路径不能有中文
|
||||||
|
- 请使用python3.9(推荐使用anconda)
|
||||||
|
|
||||||
|
### 使用yolov8n 但是下载的是yolo11n
|
||||||
|
|
||||||
|
- 删除文件夹里的yolov8n.pt即可。(其实可以直接用11了,速度更快,效果更好)
|
BIN
docs/img/1.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
docs/img/10.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
docs/img/11.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
docs/img/12.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
docs/img/13.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
docs/img/14.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/img/15.png
Normal file
After Width: | Height: | Size: 189 KiB |
BIN
docs/img/2.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
docs/img/3.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
docs/img/4.png
Normal file
After Width: | Height: | Size: 418 KiB |
BIN
docs/img/5.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/img/6.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
docs/img/7.png
Normal file
After Width: | Height: | Size: 121 KiB |
BIN
docs/img/8.png
Normal file
After Width: | Height: | Size: 224 KiB |
BIN
docs/img/9.png
Normal file
After Width: | Height: | Size: 24 KiB |
29
scripts/1080p.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# 使用前需要安装Pillow pip install Pillow
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
import os
|
||||||
|
|
||||||
|
def resize_to_1080p(image_path):
|
||||||
|
try:
|
||||||
|
with Image.open(image_path) as img:
|
||||||
|
# 获取图像的原始尺寸
|
||||||
|
original_width, original_height = img.size
|
||||||
|
target_size = (1920, 1080)
|
||||||
|
|
||||||
|
# 等比例缩放图像
|
||||||
|
img.thumbnail(target_size, Image.LANCZOS)
|
||||||
|
img.save(image_path)
|
||||||
|
print(f"图像已调整大小: {image_path}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"处理图像时发生错误: {e}")
|
||||||
|
|
||||||
|
def process_folder(folder_path):
|
||||||
|
for root, _, files in os.walk(folder_path):
|
||||||
|
for file in files:
|
||||||
|
if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
|
||||||
|
image_path = os.path.join(root, file)
|
||||||
|
resize_to_1080p(image_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
folder_path = r"E:\School\R\Robocon\垃圾桶\数据集"
|
||||||
|
process_folder(folder_path)
|
63
scripts/track_test.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from ultralytics import YOLO
|
||||||
|
|
||||||
|
# Load the YOLO model
|
||||||
|
model = YOLO("yolo11n.pt")
|
||||||
|
# model = YOLO("yolov8n.pt")
|
||||||
|
# model = YOLO("your_yolo_model.pt")
|
||||||
|
|
||||||
|
# Open the video file
|
||||||
|
# video_path = "path/to/video.mp4"
|
||||||
|
cap = cv2.VideoCapture(0)
|
||||||
|
|
||||||
|
# Store the track history
|
||||||
|
track_history = defaultdict(lambda: [])
|
||||||
|
|
||||||
|
# Loop through the video frames
|
||||||
|
while cap.isOpened():
|
||||||
|
# Read a frame from the video
|
||||||
|
success, frame = cap.read()
|
||||||
|
|
||||||
|
if success:
|
||||||
|
results = model.track(frame, persist=True)
|
||||||
|
# print(results)
|
||||||
|
boxes = results[0].boxes.xywh.cpu()
|
||||||
|
track_ids = results[0].boxes.id
|
||||||
|
|
||||||
|
if track_ids is not None:
|
||||||
|
track_ids = track_ids.int().cpu().tolist()
|
||||||
|
|
||||||
|
# Visualize the results on the frame
|
||||||
|
annotated_frame = results[0].plot()
|
||||||
|
|
||||||
|
# Plot the tracks
|
||||||
|
for box, track_id in zip(boxes, track_ids):
|
||||||
|
x, y, w, h = box
|
||||||
|
track = track_history[track_id]
|
||||||
|
track.append((float(x), float(y))) # x, y center point
|
||||||
|
if len(track) > 30: # retain 90 tracks for 90 frames
|
||||||
|
track.pop(0)
|
||||||
|
|
||||||
|
# Draw the tracking lines
|
||||||
|
points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
|
||||||
|
cv2.polylines(annotated_frame, [points], isClosed=False, color=(230, 230, 230), thickness=10)
|
||||||
|
else:
|
||||||
|
annotated_frame = frame
|
||||||
|
|
||||||
|
# Display the annotated frame
|
||||||
|
cv2.imshow("YOLO11 Tracking", annotated_frame)
|
||||||
|
|
||||||
|
# Break the loop if 'q' is pressed
|
||||||
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Break the loop if the end of the video is reached
|
||||||
|
break
|
||||||
|
|
||||||
|
# Release the video capture object and close the display window
|
||||||
|
cap.release()
|
||||||
|
cv2.destroyAllWindows()
|
29
scripts/turn_img.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# 使用前需要安装Pillow pip install Pillow
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
import os
|
||||||
|
|
||||||
|
def rotate_to_landscape(image_path):
|
||||||
|
try:
|
||||||
|
with Image.open(image_path) as img:
|
||||||
|
width, height = img.size
|
||||||
|
if height > width:
|
||||||
|
# 旋转图像使其变为横向
|
||||||
|
rotated_img = img.rotate(90, expand=True)
|
||||||
|
rotated_img.save(image_path)
|
||||||
|
print(f"图像已旋转: {image_path}")
|
||||||
|
else:
|
||||||
|
print(f"图像已是横向: {image_path}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"处理图像时发生错误: {e}")
|
||||||
|
|
||||||
|
def process_folder(folder_path):
|
||||||
|
for root, _, files in os.walk(folder_path):
|
||||||
|
for file in files:
|
||||||
|
if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
|
||||||
|
image_path = os.path.join(root, file)
|
||||||
|
rotate_to_landscape(image_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
folder_path = "E:\School\R\Robocon\垃圾桶\数据集"
|
||||||
|
process_folder(folder_path)
|
6
yolo.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
train: E:\School\R\Robocon\YOLOv8\datasets\images\train #训练集图片绝对路径
|
||||||
|
val: E:\School\R\Robocon\YOLOv8\datasets\images\val #数据集绝对路径
|
||||||
|
# number of classes
|
||||||
|
nc: 2 #类别数
|
||||||
|
# class names
|
||||||
|
names: ['blue', 'red'] #类别名称
|