视觉学习yolo+OpenCV(电赛准备)

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

       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'strUltralytics 设置版本(有别于Ultralytics pip版本)
datasets_dir'/path/to/datasets'str存储数据集的目录
weights_dir'/path/to/weights'str存储模型权重的目录
runs_dir'/path/to/runs'str存储实验运行的目录
uuid'a1b2c3d4'str当前设置的唯一标识符
syncTruebool将分析和崩溃同步到Ultralytics HUB的选项
api_key''strUltralytics HUBAPI 密钥
clearmlTruebool使用以下选项 ClearML记录
cometTruebool使用Comet ML进行实验跟踪和可视化的选项
dvcTruebool可选择使用DVC 进行实验跟踪和版本控制
hubTruebool使用Ultralytics HUB集成选项
mlflowTruebool使用MLFlow进行实验跟踪的选项
neptuneTruebool可选择使用 Neptune进行实验跟踪
raytuneTruebool使用Ray Tune进行超参数调整的选项
tensorboardTruebool使用TensorBoard进行可视化的选项
wandbTruebool使用选项 Weights & Biases记录
vscode_msgTruebool检测到 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-configUI 布局或快捷键错乱时一键还原
版本查看--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/trainlabels/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()

后续接下来做电赛的识别激光的训练,用树莓派试试

参考链接:

yolo文档

https://zhuanlan.zhihu.com/p/371756150

Labelme json文件转换为yolo标签格式文件_lableme json转yolo格式-优快云博客

使用 OpenCV 和 YOLO 模型进行实时目标检测并在视频流中显示检测结果_yolo实时视频流检测-优快云博客

海康培训--基础技术课程前端-摄像机常见参数解读_哔哩哔哩_bilibili

OpenCV中文文档

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

01bigdata

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值