在上一篇文章(https://blog.csdn.net/walchina2017/article/details/130334374)中,我介绍了什么是实时学习,并且开源了一个我做出来的作品。

接下来,我会手把手教你如何把它做出来。

首先,你得先下载Pycharm(https://www.jetbrains.com/pycharm/download/)和Python(有镜像),并知道如何在Pycharm中新建一个Project。

然后,新建一个Project,选择Virualvenv,然后点击创建:

等Pycharm创建完虚拟环境(Virtualvenv)后,会出现这个界面。

接下来,点击画红圈的地方来打开Terminal。

接着,在Terminal中输入:pip install ultralytics -i https://pypi.douban.com/simple --trusted-host pypi.douban.com,然后点击回车键来安装所需要的Python库:

接着,在你的文件浏览器中找到你的项目的文件夹,并打开它。根据下图所显示的列表新建这些文件夹:

注:在dataset一下的所有文件夹都必须是和上图列表一样的,否则无法训练模型。

接着,把在train · main · 何荣基 / Real Time Learning Yolov8 · GitCode中的yolov8n-face.pt 和 costum_data.yaml 下载到train文件夹内,文件列表应该是这样的:

接下来,进入右边的编辑器里,删掉所有的代码,我们要开始编写我们自己的代码了:

1. 导入所需要的库:

import cv2
from threading import Thread
import numpy as np
from ultralytics import YOLO

cv2: opencv-python的简称,可以帮助我们打开摄像头,并获取实时图像。

threading(Python自带): 可以让多个代码同时运行

numpy:可以进行复杂的矩阵乘法,还可以把tensor类型转换成numpy。

ultralytics:Yolo的官方PythonAPI,可以在代码中实现训练,而不需要CLI。

2. 做一个简单的用cv2打开摄像头的程序:

import cv2
from threading import Thread
import numpy as np
from ultralytics import YOLOcap = cv2.VideoCapture(0)while True:ret, frame = cap.read()cv2.imshow('returned', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()

cap = cv2.VideoCapture(0):将cap设为摄像头

ret, frame = cap.read():读取摄像头的画面

cv2.imshow('returned', frame):显示摄像头看到的东西,并将打开的窗口的名字设为return.

if cv2.waitKey(1) & 0xFF == ord('q'):检测q键是否按下, 如果是的话,就强制推出while循环。

cap.release():关闭摄像头

cv2.destroyAllWindows():把所有窗口都关闭。

我们来试一试效果:

接下来,我们就得实现检测到人脸,并且画出来位置:

1.

import cv2
from threading import Thread
import numpy as np
from ultralytics import YOLOmodel = YOLO('train/train_yolov8n-face.pt')cap = cv2.VideoCapture(0)while True:ret, frame = cap.read()results = model.predict(frame)annotated = results[0].plot()cv2.imshow('returned', annotated)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()

model = YOLOY('train/train_yolov8n-face.pt'):把要运算的模型设为YOLO模型,位置在相对路径 train/yolov8n-face.pt(注意:应为yolov8n-face.pt是从gitee上下载下来的,名字会改成train_yolov8n-face.pt)

results = model.predict(frame):检测人脸

results[0].plot():把人脸的位置画出来。

cv2.imshow('returned', annotated):把画出来的位置显示出来(注意,第二个参数已经换成了annotated,而不是frame)

让我们俩看一看效果:

然后,我们需要把‘问题’和‘回答’记录下来:

import cv2
from threading import Thread
import numpy as np
from ultralytics import YOLOmodel = YOLO('train/train_yolov8n-face.pt')cap = cv2.VideoCapture(0)while True:ret, frame = cap.read()results = model.predict(frame)boxes = result[0].boxesif bool(boxes.numpy()):if face_count < 300:face_count += 1else:face_count = 0# 获取人脸位置信息# 保存人脸图像和位置信息到文件if face_count >= 0 and face_count < 100:# 记录到验证集filepath = f'train/dataset/images/val/{face_count}.png'labelspath = f'train/dataset/labels/val/{face_count}.txt'else:# 记录到训练集filepath = f'train/dataset/images/train/{face_count}.png'labelspath = f'train/dataset/labels/train/{face_count}.txt'# 保存人脸图像cv2.imwrite(filepath, frame)# 保存位置信息到文件with open(labelspath, 'w') as file:for bboxes in boxes:for xywh in bboxes.xywh:xywh = xywh * np.array([1/frame.shape[1], 1/frame.shape[0], 1/frame.shape[1], 1/frame.shape[0]])file.write(f'0 {xywh[0]} {xywh[1]} {xywh[2]} {xywh[3]}\n')file.close()annotated = results[0].plot()cv2.imshow('returned', annotated)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()

夸嚓一下多了这么多行代码,是不是有点蒙?没事,我会慢慢帮你讲解。

第一部分:

boxes = result[0].boxes
if bool(boxes.numpy()):if face_count < 300:face_count += 1else:face_count = 0

if bool(boxes.numpy()) 使用后来检测有咩有检测到人脸,这样就可以预防没有人脸的照片被录入训练文件夹。

这个是用来数有多少数据被收集了,如果超过300,就会归零。

第二部分:

# 保存人脸图像和位置信息到文件if face_count >= 0 and face_count < 100:# 记录到验证集filepath = f'train/dataset/images/val/{face_count}.png'labelspath = f'train/dataset/labels/val/{face_count}.txt'else:# 记录到训练集filepath = f'train/dataset/images/train/{face_count}.png'labelspath = f'train/dataset/labels/train/{face_count}.txt'

首先,我们需要知道Yolov8在被训练的时候是需要train数据集和val数据集的,所以,我们决定把1/3的数据给val数据集,然后把剩下的2/3给train数据集。

第三部分:

    # 保存人脸图像cv2.imwrite(filepath, frame)# 保存位置信息到文件with open(labelspath, 'w') as file:for bboxes in boxes:for xywh in bboxes.xywh:xywh = xywh * np.array([1/frame.shape[1], 1/frame.shape[0], 1/frame.shape[1], 1/frame.shape[0]])file.write(f'0 {xywh[0]} {xywh[1]} {xywh[2]} {xywh[3]}\n')file.close()

我们会用cv2.imwrite把没有标记的图片记录下来(我们记录下来的的图片是frame,也就是摄像头实时读取的数据)。

接着,就到了把标记的参数记录下来。我们知道 yolo_label 的格式是这样的:

0 x_center/width_of_image y_center/img_heighy width/img_width height/img_height

在上一部分里有一个变量叫boxes,它被设为result[0].boxes。在result[0].boxes中有很多格式选项,但是只有result[0].boxes.xywh符合我们的要求。x在xywh中的意思就是bbox的x轴中心点,y在xywh中的意思就是bbox的y轴中心点,w在xywh中的意思就是bbox的宽度,而h在xywh中的意思就是bbox的高度。

我们只需要把数据乘以 [1/frame.shape[1](frame的宽度), 1/frame.shape[0] (frame的高度), 1/frame.shape[1](frame的宽度), 1/frame.shape[0] (frame的高度)]就可以了。

但是,bboxes.xywh的输出格式是tensor格式(tensor([x,xx,xxx,xxxx])),所以我们还要把它乘以一个numpy格式的列表才能同化tensor格式的列表。

最后就是把数据写到指定的文件夹中的一个.txt格式中。

最后,我们要实现训练模型。

先打开在train中的train_custom_data.yaml。

可以看到train和val数据集已经被设置好。

接下来就开始先训练模块了:

import cv2
from threading import Thread
import numpy as np
from ultralytics import YOLOdef train_it():global model, trainingdef do():global model, training# 训练模型model.train(data='train/custom_data.yaml', epochs=epochs)# 将在训练设为 False(不在训练)training = FalseThread(target=do).start()model = YOLO('train/train_yolov8n-face.pt')training = Falsecap = cv2.VideoCapture(0)while True:ret, frame = cap.read()results = model.predict(frame)boxes = result[0].boxesif not training:if bool(boxes.numpy):# 检测是否需要继续记录人脸if face_count < 300:face_count += 1else:# 开始训练新模型train_it()# 将在训练设为 True(在训练)training = True# 重置人脸录取次数face_count = 0# 获取人脸位置信息# 保存人脸图像和位置信息到文件if face_count >= 0 and face_count < 100:# 记录到验证集filepath = f'train/dataset/images/val/{face_count}.png'labelspath = f'train/dataset/labels/val/{face_count}.txt'else:# 记录到训练集filepath = f'train/dataset/images/train/{face_count}.png'labelspath = f'train/dataset/labels/train/{face_count}.txt'# 保存人脸图像cv2.imwrite(filepath, frame)# 保存位置信息到文件with open(labelspath, 'w') as file:for bboxes in boxes:for xywh in bboxes.xywh:xywh = xywh * np.array([1/frame.shape[1], 1/frame.shape[0], 1/frame.shape[1], 1/frame.shape[0]])file.write(f'0 {xywh[0]} {xywh[1]} {xywh[2]} {xywh[3]}\n')file.close()annotated = results[0].plot()cv2.imshow('returned', annotated)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()

天哪!

还是老样子,我们拆分一下新增的程序:

第一部分:

def train_it():global model, trainingdef do():global model, training# 训练模型model.train(data='train/train_custom_data.yaml', epochs=epochs)# 将在训练设为 False(不在训练)training = FalseThread(target=do).start()training = False

我们新加了一个函数,来训练新的模型,所以要global model。

我们新加training是应为我们不想要AI在学习的时候数据会改变,所以在学习的时候就会停止录取数据。

为了实现这个,我们在需要在负责记录的模块前面加一个if语句,这样的话,只有training是False(没有在训练)的时候才会记录数据。

第二部分:

if not training:if bool(boxes.numpy()):# 检测是否需要继续记录人脸if face_count < 300:face_count += 1else:# 开始训练新模型train_it()# 将在训练设为 True(在训练)training = True# 重置人脸录取次数face_count = 0

现在我们可以看到else下面加了一些代码,这些是用来启动训练程序的。

train_it():这个是启动训练模型的。我们把train_it函数设为thread,这可以让训练和检测同时进行。

当启动完成后,training就会被设为True(在训练),这样就可防止AI在训练的时候还在记录数据,导致数据变化。

每次训练的结果都能在runs/detect/trainx/weights中找到(x是第几个被训练的模型)。比如说,我想要第七次被训练的模型,就得进入这个文件路径:runs/detect/train9/weights/best.pt。

最后,让我们测试一下(这里的epochs是2,有可能比较慢,所以我就快进一下):

看到视频里的进度条了吗?这个进度条就是训练完成了多少。虽然只是2个epochs,但是还是用了10分钟(没有加速的原始视频),如果电脑的配置高一点会更快。

但这不是重点,重点是训练和检测可以同步执行,并且新的模型和旧的模型可以无缝衔接!

OK!这个教程到这里就结束啦!最后,整理一下代码:

# 导入需要的库
import cv2
from threading import Thread
import numpy as np
from ultralytics import YOLO# 初始化变量
def init_variables():# 导入人脸检测模型model = YOLO("train/train_yolov8n-face.pt")# 初始化同步运行训练模块#train_new_yolo = Thread(target=train_it)# 初始化人脸录取数变量face_count = 0# 初始化是否在训练中变量training = False# 初始化 epochsepochs = 5# 初始化摄像头cap = cv2.VideoCapture(0)MAX_FACE_COUNT = 600VALIDATION_SPLIT_COUNT = 200return model, face_count, training, epochs, cap, MAX_FACE_COUNT, VALIDATION_SPLIT_COUNT# 记录人脸函数
def record_faces(frame, result):global face_count, training, model# 训练函数def train_it():global model, trainingdef do():global model, training# 训练模型model.train(data='train/train_custom_data.yaml', epochs=epochs)# 将在训练设为 False(不在训练)training = FalseThread(target=do).start()# 检测是否在训练if not training:boxes = result[0].boxesif bool(boxes.numpy()):#检测是否需要继续记录人脸if face_count < MAX_FACE_COUNT:face_count += 1else:# 开始训练新模型train_it()# 将在训练设为 True(在训练)training = True# 重置人脸录取次数face_count = 0# 获取人脸位置信息boxes = result[0].boxes# 保存人脸图像和位置信息到文件if face_count >= 0 and face_count < VALIDATION_SPLIT_COUNT:# 记录到验证集filepath = f'train/dataset/images/val/{face_count}.png'labelspath = f'train/dataset/labels/val/{face_count}.txt'else:# 记录到训练集filepath = f'train/dataset/images/train/{face_count}.png'labelspath = f'train/dataset/labels/train/{face_count}.txt'# 保存人脸图像cv2.imwrite(filepath, frame)# 保存位置信息到文件with open(labelspath, 'w') as file:for bboxes in boxes:for xywh in bboxes.xywh:xywh = xywh * np.array([1 / frame.shape[1], 1 / frame.shape[0], 1 / frame.shape[1], 1 / frame.shape[0]])file.write(f'0 {xywh[0]} {xywh[1]} {xywh[2]} {xywh[3]}\n')file.close()
model,face_count, training, epochs, cap, MAX_FACE_COUNT, VALIDATION_SPLIT_COUNT = init_variables()while True:# 读取实时图像ret, frame = cap.read()# 获取检测的结果results = model.predict(frame, show=False)# 记录人脸record_faces(frame, results)# 在图像上绘制检测结果annotated = results[0].plot()# 显示画出来的效果cv2.imshow('returned', annotated)# 检测是否要退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放摄像头并关闭窗口
cap.release()
cv2.destroyAllWindows()

最后,来看一下我搞出来的结果:

原始模型:

实时训练3次,epochs=5, MAX_FACE_COUNT=600,VALIDATION_SPLIT_COUNT=200:

可以看到无论是P,还是R,还是mAP50,或是mAP50-95都有显著的提升,mAP50-95更是从71%提到了95%。

实时训练Real-Time Training 教程相关推荐

  1. QIIME 2教程. 13训练特征分类器Training feature classifiers(2020.11)

    文章目录 训练特征分类器 下载并导入参考序列 提取参考序列 训练分类集 测试分类集 分类真菌ITS序列 译者简介 译者简介 Reference 猜你喜欢 写在后面 训练特征分类器 Training f ...

  2. QIIME 2用户文档. 13训练特征分类器Training feature classifiers(2019.7)

    前情提要 NBT:QIIME 2可重复.交互和扩展的微生物组数据分析平台 1简介和安装Introduction&Install 2插件工作流程概述Workflow 3老司机上路指南Experi ...

  3. QIIME 2用户文档. 12训练特征分类器Training feature classifiers(2018.11)

    文章目录 前情提要 训练特征分类器 下载并导入参考序列 提取参考序列 训练分类集 测试分类集 分类真菌ITS序列 Reference 译者简介 猜你喜欢 写在后面 前情提要 QIIME 2可重复.交互 ...

  4. OpenCV级联分类器训练与使用实战教程-贾志刚-专题视频课程

    OpenCV级联分类器训练与使用实战教程-1012人已学习 课程介绍         基于OpenCV新版本3.1.0详细讲述了HAAR与LBP级联分类器的基本原理与使用技巧,通过视频中人脸实时检测与 ...

  5. [转]语音识别中区分性训练(Discriminative Training)和最大似然估计(ML)的区别...

    转:http://blog.sina.com.cn/s/blog_66f725ba0101bw8i.html 关于语音识别的声学模型训练方法已经是比较成熟的方法,一般企业或者研究机构会采用HTK工具包 ...

  6. 不需要借助GPU的力量,用树莓派也能实时训练agent玩Atari

    点击上方↑↑↑"视学算法"关注我 来源:公众号 机器之心 授权 还是熟悉的树莓派!训练 RL agent 打 Atari 不再需要 GPU 集群,这个项目让你在边缘设备上也能进行实 ...

  7. C语言oj学生成绩输入和输出,『ACM入门』蓝桥杯ACM训练系统基本输入输出教程

    在介绍训练场的OJ系统之前,首先为大家介绍一下ACM: ACM原代表美国计算机协会,因其举办的ICPC即国际大学生程序设计竞赛而闻名全世界,此项赛事要求学生的在五小时内解决全英文问题,并在效率和速度以 ...

  8. EfficientDet训练数据集anchor设定教程101

    EfficientDet训练数据集anchor设定教程101 本文由小肉包老师原创,转载请注明出处,来自腾讯.阿里等一线AI算法工程师组成的QQ交流群欢迎你的加入: 1037662480 上一篇文章我 ...

  9. 量化交易-利用同花顺量化平台supermind 5行代码搞定多条件选股并微信实时收消息-保姆级教程

    利用supermind 5行代码搞定多条件选股并在微信实时收消息-保姆级教程 前言 对大部分炒股的朋友来说,日常最耗时的就是盯着选股条件然后不停的选股,我经常苦恼于有无程序能自动化实现选股,然后选中之 ...

最新文章

  1. 程序员吐槽:去再好的互联网公司也就是个打工仔,还累出一身病
  2. Struts2 单个文件上传/多文件上传
  3. 功能奇数次执行和偶数次执行时的结果不同的故障复盘
  4. SAP UI5 应用开发教程之六十八 - 如何实现 SAP UI5 路由失败时显示自定义的 NOT Found 页面
  5. 筋斗云newcloud错误码列表
  6. 计算机a类论文汇报,计算机学院2014年度发表和录用CCFA类、B类论文统计(初稿.xls...
  7. VS web停止调试后关闭浏览器
  8. 【LeetCode每天一题】Permutations(排列组合)
  9. 中国书写工具行业市场供需与战略研究报告
  10. Eclipse debug ‘Source not found’
  11. usb摄像头做教学直播实现pc和手机都可以在线观看教程
  12. vue监听浏览器进入页面_vue禁止浏览器F5进行刷新和监听浏览器刷新事件
  13. 什么是计算机网络AP,AP与AC的区别是什么,拓扑网络知识。
  14. pytest多文件执行顺序控制
  15. 古代平朔历法基本算法
  16. Hyper-V 2016 系列教程50 某德国制造型企业上线案例分享
  17. 华为南研所校招软件技术岗几点建议
  18. 目标检测-VOC数据集txt文件制作方法
  19. 解决清华大学校园网自动连接问题
  20. python写入csv文件中添加行_在python中为csv文件输出键添加值

热门文章

  1. loj#6100. 「2017 山东二轮集训 Day1」第一题 主席树+二分
  2. 给select里面的option加入背景图片(select美化)
  3. Espresso Idling Resource
  4. python读取配置文件列表失败_从配置文件python中读取列表
  5. Mvp+OkHttp+XRecyclerView------上拉加载下拉刷新
  6. 【LSTM分类】基于双向长短时记忆(BiLSTM)实现数据分类含Matlab源码
  7. AP计算机科学笔记,AP想5分,不看过来人的笔记怎么行?
  8. visual studio 2019 mac 格式化代码快捷键
  9. SpringBoot整合Shiro搭建登录注册认证授权权限项目模板
  10. hangfire mysql_Hangfire 在.NET Core环境的使用