YOLO(You Only Look Once)是一种实时目标检测系统,它是一种基于深度学习的目标检测算法,具有速度快、易于集成和部署、对小目标检测效果好等优点。
一、yolo和opencv的安装
打开anaconda,切换到自己所需要的环境,然后输入下面的代码就能够安装了
pip install ultralytics opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
二、修改yolo环境配置
笔者不喜欢很多东西都塞到C盘,所以一开始就修改了部分的默认设置,不过不知道后面会不会有啥影响,但是目前为止,暂时没有啥影响。
使用Python 通过导入 settings 对象的 ultralytics 模块。使用这些命令打印和返回设置:
from ultralytics import settings
# View all settings
print(settings)
# Return a specific setting
value = settings["runs_dir"]
返回如下:

下表是关于参数的介绍
| 名称 | 示例值 | 数据类型 | 说明 |
|---|---|---|---|
settings_version | '0.0.6' | str | Ultralytics 设置版本(有别于Ultralytics pip版本) |
datasets_dir | '/path/to/datasets' | str | 存储数据集的目录 |
weights_dir | '/path/to/weights' | str | 存储模型权重的目录 |
runs_dir | '/path/to/runs' | str | 存储实验运行的目录 |
uuid | 'a1b2c3d4' | str | 当前设置的唯一标识符 |
sync | True | bool | 将分析和崩溃同步到Ultralytics HUB的选项 |
api_key | '' | str | Ultralytics HUBAPI 密钥 |
clearml | True | bool | 使用以下选项 ClearML记录 |
comet | True | bool | 使用Comet ML进行实验跟踪和可视化的选项 |
dvc | True | bool | 可选择使用DVC 进行实验跟踪和版本控制 |
hub | True | bool | 使用Ultralytics HUB集成选项 |
mlflow | True | bool | 使用MLFlow进行实验跟踪的选项 |
neptune | True | bool | 可选择使用 Neptune进行实验跟踪 |
raytune | True | bool | 使用Ray Tune进行超参数调整的选项 |
tensorboard | True | bool | 使用TensorBoard进行可视化的选项 |
wandb | True | bool | 使用选项 Weights & Biases记录 |
vscode_msg | True | bool | 检测到 VS Code 终端时,启用下载Ultralytics扩展的提示。 |
需要修改可以在json文件直接修改或者python输入以下代码
from ultralytics import settings
# Update a setting
settings.update({"runs_dir": "/path/to/runs"})
# Update multiple settings
#settings.update({"runs_dir": "/path/to/runs", "tensorboard": False})
# Reset settings to default values
#settings.reset()
三、yolo部分python的快速使用
1、加载预训练模型进行照片和视频流的预测
首次运行自动下载,也可以看官方文档用v11,这里作者后面想移植到树莓派上结合opencv。
from ultralytics import YOLO
#首次运行自动下载,也可以看官方文档用v11,这里主包后面想移植到树莓派
a1 = YOLO('yolov5n.pt')

之后作者随便找了一张图片

这个也是官方教程里下载下来的图片,然后运行下面的代码
model('bus.jpg',show=True,save=True)
之后这个预测的图片就会保存到你的run下的文件夹

预测的效果如下:

接下来做的是视频流的追踪,不过作者忘记下载视频,就附上一段爬虫代码下载b站上的视频,爬取汽车流的代码如下:
#b站爬取代码
# 导入数据请求模块
import requests
# 导入正则表达式模块
import re
# 导入json模块
import json
# TODO 记得更改你要的url和你自己的cookie
url = 'https://www.bilibili.com/video/BV1uS4y1v7qN/?spm_id_from=333.337.search-card.all.click&vd_source=f4f695a55bf2a7e583ebd8706d656a4f'
cookie = "buvid3=2844B77E-F527-FB05-1DF5-9FDF834AE3E888277infoc; b_nut=1709986388; i-wanna-go-back=-1; b_ut=7; _uuid=6577D687-BED9-9AE2-106A10-551210627F5AC88087infoc; enable_web_push=DISABLE; buvid4=5ED5B3A0-A998-7D47-3815-9AD9A1B27A4989131-024030912-0Fw3r6dKwZLwPoWOl%2F8HuA%3D%3D; CURRENT_FNVAL=4048; rpdid=|(u|Jmkkuukk0J'u~u|ulR~)~; header_theme_version=CLOSE; fingerprint=c27c0b59dd10dcdc4c14701a58f49669; buvid_fp_plain=undefined; buvid_fp=c27c0b59dd10dcdc4c14701a58f49669; LIVE_BUVID=AUTO6217111182462626; FEED_LIVE_VERSION=V_WATCHLATER_PIP_WINDOW3; bp_video_offset_691902317=925084214145056785; DedeUserID=691902317; DedeUserID__ckMd5=ead312019baad7ed; CURRENT_QUALITY=80; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTYwNDM3MDgsImlhdCI6MTcxNTc4NDQ0OCwicGx0IjotMX0.Rdjc9F5oiEXSn_GylRWm3s2L-Pn8GYfyQS5IZt_Y3-8; bili_ticket_expires=1716043648; SESSDATA=3d6f944f%2C1731336513%2C491d2%2A51CjD5jp6zedAz4nQallTN_akUjFzg2LzJhdKMiJbI1nnw2bs5sp8Y09F7Jj4PofjUyfsSVlktMkF0aDRLN196dVNTeWh0czllbFZTWDlidWRpcnFnaENSNVVNbGNFMGR5bFBqYkcwalhuVklyUGJLVHJtYXo3TVpaTENqQ21rS0RPbldWTDUzRFp3IIEC; bili_jct=2975523315e5bccfa606ac286df61f36; home_feed_column=4; browser_resolution=1396-639; sid=6gr3y4l0; PVID=4; bp_t_offset_691902317=932475264446758937; b_lsid=5E9C415B_18F86EC150D"
headers = {
# Referer 防盗链 告诉服务器你请求链接是从哪里跳转过来的
# "Referer": "https://www.bilibili.com/video/BV1454y187Er/",
"Referer": url,
# User-Agent 用户代理, 表示浏览器/设备基本身份信息
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Cookie": cookie
}
# 发送请求
response = requests.get(url=url, headers=headers)
html = response.text
# 解析数据: 提取视频标题
title = re.findall('title="(.*?)"', html)[0]
print(title)
# 提取视频信息
info = re.findall('window.__playinfo__=(.*?)</script>', html)[0]
# info -> json字符串转成json字典
json_data = json.loads(info)
# 提取视频链接
video_url = json_data['data']['dash']['video'][0]['baseUrl']
print(video_url)
video_content = requests.get(url=video_url, headers=headers).content
# 保存数据
with open(title + '.mp4', mode='wb') as v:
v.write(video_content)
爬取完视频后,再进行检测

进行检测,之后再进行识别
model('车辆检测和交通流量测试视频.mp4',show=True,save=True)

2、构建自己的数据集并训练
接下来,做完基础的trace任务,开始训练自己的模型。
首先在自己的项目下创建文件夹如下:


同时我的py文件与task是同一个层级的
接下来先给大家介绍一下几个常见的标注工具
- label studio:这是一款灵活的工具,支持多种标注任务,并具有管理项目和质量控制功能。
- CVAT:功能强大的工具,支持各种注释格式和可定制的工作流程,适用于复杂的项目。
- labelme:这是一款简单易用的工具,可使用多边形快速标注图像,非常适合完成简单的任务。
- labelImg:易于使用的图形图像注释工具,尤其适合创建YOLO 格式的边界框注释。
这里作者最后使用了labelme这个工具进行数据标注(你可以直接点击上面的访问GitHub链接,查看如何下载)
作者这里是用pip下载的,但是由于自己电脑是win系统,所以可能只安装pyqt5不够的,还得多安装一个PyQt5-tools才能打开GUI
pip install labelme PyQt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple
如果还有啥其他的问题,读者可以留言或者自己debug,毕竟作者也是边学边记录。安装好后,也是如愿打开了GUI界面

之后作者决定抓取chiikawa的图片和视频进行训练。
这里先列一下labelme的一些指令参数(ps:可以用labelme -h查看),直接终端打labelme再选择文件也问题不大。
| 场景 | 关键参数 | 含义与示例 |
|---|---|---|
| 启动即标注 | filename | 直接给出待标注的图片或已有的 JSON 文件 |
| 批量输出 | --output/-O/-o | 指定结果保存位置 |
| 预定义标签 | --labels | 一次性加载标签,避免每次手动输入 |
| 标签属性/多选 | --flags | 为每个实例打复选框属性,如遮挡、截断 |
| 标签专属属性 | --labelflags | 不同标签有不同的下拉属性 |
| 不保存原图 | --nodata | 生成的 JSON 中不再内嵌 base64 原图,体积更小 |
| 自动保存 | --autosave | 每改一次就自动写盘,避免断电丢失 |
| 保持上一帧标注 | --keep-prev | 视频/序列帧场景下,下一帧继承上一帧结果,仅需微调 |
| 关闭标签排序 | --nosortlabels | 标签按给定顺序显示,不自动按字母排序 |
| 标签严格匹配 | --validatelabel exact | 输入时强制用预定义标签名,防止拼错 |
| 捕捉容差 | --epsilon | 拖拽顶点吸附半径(像素),默认 10,精细标注可调小 |
| 日志级别 | --logger-level | 调 bug 时改成 debug:--logger-level debug |
| 恢复默认配置 | --reset-config | UI 布局或快捷键错乱时一键还原 |
| 版本查看 | --version/-V | 快速确认当前 labelme 版本号 |
常见组合示例如下:
# 1) 单张图片,预设标签,结果保存同级目录
labelme cat.jpg --labels "cat,eye,nose" --output cat.json --autosave
# 2) 批量图片,预定义标签集文件,统一输出目录
labelme imgs/ -o labels/ --labels mylabels.txt --nodata --autosave
# 3) 视频帧继承标注,带复选属性
labelme frames/ --labels person.txt --flags occluded,truncated --keep-prev
之后将labelme的标注保存在label文件下,并且需要把json文件格式转化成txt文件格式。
先在anaconda prompt环境下输入
pip install labelme2yolo -i https://pypi.tuna.tsinghua.edu.cn/simple
之后输入
labelme2yolo --json_dir labels/train --output_format bbox
labelme2yolo --json_dir labels/val --output_format bbox
脚本会在原目录旁自动生成 YOLODataset/labels/train|val/*.txt,再把生成的 txt 拷回 labels/train 和 labels/val 即可训练
准备好数据集。
接下来创建一个yaml格式的文件

之后输入以下代码:
from ultralytics import YOLO
model = YOLO('yolov5nu.pt')
model.train(
data = 'chiikawa_test.yaml', #数据集配置文件路径
epochs = 100, #训练轮次
imgsz=640, #官方推荐640
batch=16, #每次训练的批量
)
就可以开始训练了,不过应该还是gpu训练比较快,建议自己的电脑上训练完模型,把模型拷到树莓派玩。

作者的训练效果不大好,还需要调参一下,但是一个是数据集只有50个,另一个是我训练集和验证集都是一起的,还有标注可能不大行,还是得调参。
但是最后文件保存在train4文件夹下,看看有什么东西。

有一些曲线图,还有相关的权重文件,接下来,我们使用权重文件进行检测。
chiikawa_model = YOLO(r'D:\ProgramData\yolo\runs\detect\train4\weights\best.pt')
chiikawa_model('小八ai还原Chiikawa259话.mp4',show = True,save=True)
最后识别出来的效果如下:

四、OpenCV快速应用
首先的话先补充一部分摄像头前端参数的知识,之后的OpenCV大部分是进行前端处理的作用。
| 参数类别 | OpenCV 枚举名(C++/Python) | 含义 | 典型取值范围 | 备注 |
|---|---|---|---|---|
| 分辨率 | CAP_PROP_FRAME_WIDTH / HEIGHT | 图像宽、高 | 如 640×480、1920×1080 | 需硬件支持;MJPG 格式才能跑高分辨率+高帧率 |
| 帧率 | CAP_PROP_FPS | 每秒帧数 | 5–120 | 同上 |
| 编码格式 | CAP_PROP_FOURCC | 像素格式/压缩格式 | ‘MJPG’、‘YUYV’ | 1080p 实时建议 MJPG |
| 亮度 | CAP_PROP_BRIGHTNESS | 全局明暗 | 0–255(厂商不同) | 实时可调 |
| 对比度 | CAP_PROP_CONTRAST | 动态范围 | 0–255 | |
| 饱和度 | CAP_PROP_SATURATION | 颜色浓淡 | 0–255 | |
| 色调 | CAP_PROP_HUE | 色盘偏移 | 0–255 | |
| 伽马 | CAP_PROP_GAMMA | 非线性亮度映射 | 0–500 | 见示例 |
| 增益 | CAP_PROP_GAIN | 模拟增益 | 0–255 | 噪点随增益提升 |
| 曝光 | CAP_PROP_EXPOSURE | 曝光时间 | -13(短)~ -1(长)或绝对毫秒 | 负值越大越短;关闭自动曝光后才生效 |
| 白平衡 | CAP_PROP_WHITE_BALANCE_BLUE_U / RED_V | 色温 | 2000–10000 K | 部分相机仅支持自动/手动切换 |
| 对焦 | CAP_PROP_FOCUS | 绝对对焦距离 | 0–255 | 需要支持 UVC 连续对焦 |
| 缩放/平移 | CAP_PROP_ZOOM / PAN / TILT | 数码或光学变焦 | 0–255 | 高端 USB/工业相机才有 |
背光补偿:也称为逆光补偿,是早期应对强光或强逆光视频监控环境的方法
如果一个场景既有非常明亮的物体,也有非常黑暗的物体,亮度跨度很大,我们就称之为“高动态范围 High Dynamic Range(HDR)”场景。
下面的是一些之前为了准备电赛的代码:
1、色域追踪
通过鼠标GUI的点击,从而获取点击位置hsv属性。
import numpy as np
import cv2 as cv
#鼠标寻找色域函数
def nothing(x):
pass
def show_hsv(event,x,y,flags,param):
global ix, iy, drawing,mode
if event == cv.EVENT_LBUTTONDOWN:
ix,iy = x,y
elif event ==cv.EVENT_LBUTTONUP:
pixel_hsv = hsv[y, x]
# 打印HSV值
print(f"HSV pixel value at ({x}, {y}): Hue={pixel_hsv[0]}, Saturation={pixel_hsv[1]}, Value={pixel_hsv[2]}")
#print(type(pixel_hsv),pixel_hsv)
# 创建一个VideoCapture对象
cap = cv.VideoCapture(0)
print(cap.get(cv.CAP_PROP_FRAME_WIDTH),cap.get(cv.CAP_PROP_FRAME_HEIGHT))
while(True):
ret, frame = cap.read()
cv.namedWindow('image')
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
cv.imshow('image',frame)
#设置鼠标状态
cv.setMouseCallback('image',show_hsv)
#按q推出
if cv.waitKey(1) & 0xFF ==ord('q'):
break
#释放VideoCapture对象
cap.release()
cv.destroyAllWindows()
通过鼠标GUI的点击,从而获取点击位置bgr属性。
import numpy as np
import cv2 as cv
# 鼠标寻找色域函数
def nothing(x):
pass
def show_bgr(event, x, y, flags, param):
global ix, iy, drawing, mode
if event == cv.EVENT_LBUTTONDOWN:
ix, iy = x, y
elif event == cv.EVENT_LBUTTONUP:
bgr_pixel = frame[y, x] # 获取BGR像素值
# 打印BGR值
print(f"BGR pixel value at ({x}, {y}): Blue={bgr_pixel[0]}, Green={bgr_pixel[1]}, Red={bgr_pixel[2]}")
# 创建一个VideoCapture对象
cap = cv.VideoCapture(0)
print(cap.get(cv.CAP_PROP_FRAME_WIDTH), cap.get(cv.CAP_PROP_FRAME_HEIGHT))
while (True):
ret, frame = cap.read()
if not ret:
break
cv.namedWindow('image')
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV) # 转换为HSV空间,虽然我们不需要显示它
cv.imshow('image', frame) # 显示BGR图像
# 设置鼠标状态
cv.setMouseCallback('image', show_bgr)
# 按 'q' 退出
if cv.waitKey(1) & 0xFF == ord('q'):
break
# 释放VideoCapture对象
cap.release()
cv.destroyAllWindows()
2、设置ROI
通过顺时针点击一个矩形的四个角确定ROI的大小
import cv2 as cv
import numpy as np
# 初始化点的列表
points = []
# 定义鼠标回调函数
def set_ROI(event, x, y, flags, param):
global points
if event == cv.EVENT_LBUTTONDOWN and len(points)<=4:
points.append((x, y))
# 读取视频
cap = cv.VideoCapture(0)
while True:
# 读取视频帧
ret, frame = cap.read()
if not ret:
break
# 显示视频帧
img = frame.copy()
if len(points)==4:
cv.imshow('Video',img[points[0][0]:points[2][0],points[0][1]:points[2][1]])
if len(points)!=4:
cv.imshow('Video', img)
# 鼠标回调函数
#顺时针设置ROI
cv.setMouseCallback('Video', set_ROI)
# 等待按键,退出循环
k = cv.waitKey(1) & 0xFF
if k == 27: # 按下ESC键退出
break
# 释放视频捕获对象
cap.release()
cv.destroyAllWindows()
五、OpenCV视频流显示yolo检测的操作
原本想介绍一点opencv的知识,但是后面想了想,还是由读者自己去学习(如果有需要或者重新温习的话,还会更新这部分),可以看这个网址的知识https://apachecn.github.io/opencv-doc-zh/#/去学习
import cv2
from ultralytics import YOLO
# 加载 YOLOv8 模型
model = YOLO("yolov8n.pt")
# 打开视频文件
# cap = cv2.VideoCapture("path/to/your/video/file.mp4")
# 或使用设备“0”打开视频捕获设备读取帧
cap = cv2.VideoCapture(0)
# 设置视频帧大小
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 200)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 200)
title = "YOLOv8 Inference"
# 设置窗口位置
cv2.namedWindow(title, cv2.WINDOW_NORMAL)
cv2.moveWindow(title, 200, 200)
# 循环播放视频帧
while cap.isOpened():
# 从视频中读取一帧
success, frame = cap.read()
if success:
# 在框架上运行 YOLOv8 推理
results = model(frame)
# 在框架上可视化结果
annotated_frame = results[0].plot()
# 显示带标注的框架
cv2.imshow(title, annotated_frame)
# 如果按下“q”,则中断循环
if cv2.waitKey(1) & 0xFF == ord("q"):
break
else:
# 如果到达视频末尾,则中断循环
break
# 释放视频捕获对象并关闭显示窗口
cap.release()
cv2.destroyAllWindows()
后续接下来做电赛的识别激光的训练,用树莓派试试
参考链接:
https://zhuanlan.zhihu.com/p/371756150
Labelme json文件转换为yolo标签格式文件_lableme json转yolo格式-优快云博客
使用 OpenCV 和 YOLO 模型进行实时目标检测并在视频流中显示检测结果_yolo实时视频流检测-优快云博客
1055





