【验证码识别】Yolov8入门到实战点选验证码数据集分类训练,孪生训练,导出onnx,搭建部署接口

【验证码识别】Yolov8入门到实战点选验证码数据集分类训练,孪生训练,导出onnx,搭建部署接口

文章目录

  • 【验证码识别】Yolov8入门到实战点选验证码数据集分类训练,孪生训练,导出onnx,搭建部署接口
  • 声明
    • 一、标注验证码数据集
      • labelme标注验证码数据集
        • 1直接下载安装包
        • 2通过pip安装labelme
      • half_model_label标注验证码数据集
  • 二 、使用yolov8开始训练
    • yolov8安装使用
    • 目标检测:
    • 导出onnx使用
    • 分类训练
  • 三、孪生训练
      • 问题拆解
      • yolov5训练过程:
      • Siamese训练过程:
      • onnx介绍:
  • 四、搭建部署自己的接口

声明

本文章中所有内容仅供研究、学习交流使用,不能用作其他任何目的,严禁用于商业用途和非法用途,否则一切后果自负,与作者无关。如有侵权请联系作者删除文章

一、标注验证码数据集

labelme标注验证码数据集

1直接下载安装包

github开源地址: Releases · labelmeai/labelme (github.com)

image-20240531143450093

2通过pip安装labelme

如果你使用这种方式推荐conda进行安装虚拟环境,对于深度学习来说会方便很多

conda create -n yolov8 python=3.8
conda activate yolov8
pip install labelme

最后输入 labelme就能弹出打标界面了。

最重要的设置,每次打标都需要打开:

开启自动保存标注结果(不会每次弹窗),取消勾选Save With Image Data不把图像的编码内容保存到标注标签中。

image-20240531144526095

关键保留最后的标注可以继承上一张图的打标的框,不用每次标记图都要重新画框了,还可以保证每个标注图像大小都一样,对于后面的孪生标注很有用。

image-20240531144647500

最后将json格式的标注文件转为我们训练需要的特定格式内容:

{目标类别id} {归一化后的目标中心点x坐标} {归一化后的目标中心点y坐标} {归一化后的目标框宽度w} {归一化后的目标框高度h}。与其他数据不同的是,yolo标签只有类别id,并无具体类别名称,此外,其以相对尺寸描述标注框的xywh信息,不受图像尺寸改变的影响

image-20240531145618417

标注文件中的每一行表示一个边界框(bounding box),假设图像的宽度 W=1000,高度 H=800,有一个边界框:

  1. 类别ID 7:
    • 左上角坐标:(500,400)
    • 右下角坐标:(712, 561)

我们计算第一个边界框的归一化值:
x c e n t e r = 500 + 712 2 ⋅ 1000 = 1212 2000 = 0.606 x_{center} = \frac{500 + 712}{2 \cdot 1000} = \frac{1212}{2000} = 0.606 xcenter=21000500+712=20001212=0.606

y c e n t e r = 400 + 561 2 ⋅ 800 = 961 1600 = 0.600625 y_{center} = \frac{400 + 561}{2 \cdot 800} = \frac{961}{1600} = 0.600625 ycenter=2800400+561=1600961=0.600625

w i d t h = 712 − 500 1000 = 212 1000 = 0.212 width = \frac{712 - 500}{1000} = \frac{212}{1000} = 0.212 width=1000712500=1000212=0.212

h e i g h t = 561 − 400 800 = 161 800 = 0.20125 height = \frac{561 - 400}{800} = \frac{161}{800} = 0.20125 height=800561400=800161=0.20125
最终的到以下结果

<类别ID> <x_center> <y_center> <width> <height>
6 0.606 0.600625 0.212 0.20125

half_model_label标注验证码数据集

这个是有懒佬他们开发的,我觉得挺好用的,功能很多,大家自己去探索下。half_model_label: 半自动模型识别标注

image-20240531154548654

二 、使用yolov8开始训练

yolov8安装使用

在前面的虚拟环境中安装

pip install ultralytics
conda list ultralytics#查看安装情况

官网地址: https://github.com/ultralytics/ultralytics

如果使用gpu训练,安装CUDA、CUDNN、Python、Pytorch、Torchvision 的版本都要要相互对应 Previous PyTorch Versions | PyTorch

目标检测:

from ultralytics import YOLO

# Load a model
model = YOLO("yolov8n.yaml")  # build a new model from YAML
model = YOLO("yolov8n.pt")  # load a pretrained model (recommended for training)
model = YOLO("yolov8n.yaml").load("yolov8n.pt")  # build from YAML and transfer weights

# Train the model
results = model.train(data="coco8.yaml", epochs=100, cache=True, imgsz=320, batch=16, workers=0, device=device, resume=resume)

训练完模型使用best.pt 进行预测:

在这里插入图片描述

from ultralytics import YOLO

# Load a model
model = YOLO("yolov8n.pt")  # load an official model
model = YOLO("path/to/best.pt")  # load a custom model

# Predict with the model
results = model("https://ultralytics.com/images/bus.jpg")  # predict on an image

预测的结果相关参数可以去看官方文档:Predict - Ultralytics YOLO Docs

效果还是不错:

image-20240531161155565

导出onnx使用

最后可以导出onnx,注意imgsz=320必须和训练是参数一致。

from ultralytics import YOLO

# Load a model
model = YOLO("yolov8n.pt")  # load an official model
model = YOLO("path/to/best.pt")  # load a custom trained model

# Export the model
model.export(format="onnx")

分类训练

分类训练主要是准备数据集,如下图:

image-20240531162002078

这个是由9个格子组成的魔方,我们可以这样思考分类

如果不考虑形状,总共有 2的9次方=512 种可能的矩阵这个分类太多了。

转换为数学的方法,我们有对于一个 3x3 的矩阵,有以下几种种对称变换:

  • 顺时针旋转 90 度
  • 水平翻转
  • 垂直翻转
  • 对角线 (左上到右下) 翻转
  • 对角线 (右上到左下) 翻转
    (1 1 1)
    (1 0 1)
    (0 0 0)
    1表示黑色 0表示白色 白色不可见,我们可以算出有102种类别

先分大的类别,我们这里将有几个空格为大类别,0-9进行分类然后再细分

这里提供写的脚本:搭建的一个flask进行分类

# -*- coding: utf-8 -*-
from flask import Flask, jsonify, request, send_from_directory, render_template
import os

app = Flask(__name__)
IMAGE_FOLDER = 'data'
CLASSIFY_FOLDER = 'classify'

# 获取图片列表
@app.route('/api/images', methods=['GET'])
def get_images():
    images = [f for f in os.listdir(IMAGE_FOLDER) if f.endswith('.png')]
    return jsonify(images)

# 处理分类请求
@app.route('/api/classify', methods=['POST'])
def classify_image():
    data = request.json
    image_name = data['image']
    classification = data['classification']
    classify_folder = os.path.join(os.getcwd(), CLASSIFY_FOLDER)
    target_folder = os.path.join(classify_folder, classification)
    if not os.path.exists(target_folder):
        os.makedirs(target_folder)

    source_path = os.path.join(IMAGE_FOLDER, image_name)
    target_path = os.path.join(target_folder, image_name)
    os.rename(source_path, target_path)

    return jsonify({'message': 'success'})

# 提供图片文件
@app.route('/images/<filename>')
def send_image(filename):
    #当前文件夹
    img_path = os.path.join(os.getcwd(), IMAGE_FOLDER)
    return send_from_directory(img_path, filename)

@app.route('/')
def index():
    return render_template('demo.html')

if __name__ == '__main__':
    app.run(debug=True)

效果如下:输入类别即可

image-20240531163359049

最后在进行细分,我也不知道咋起的名字了,反正这几天打标签人都傻了,红红火火恍恍惚惚哈哈哈哈哈哈哈。

image-20240531160739860

完成细分后进行训练集,测试集,验证集进行划分:

import os
import shutil
from pathlib import Path
from random import shuffle

# 定义路径
base_dir = Path(r"D:\data\魔方细分\classify")
train_dir = base_dir / "train"
test_dir = base_dir / "test"
val_dir = base_dir / "val"
for directory in [train_dir, test_dir, val_dir]:
    directory.mkdir(exist_ok=True)

# 遍历前所以文件夹
folders = [f for f in base_dir.iterdir() if f.is_dir()][:-1]
for class_dir in folders:
    images = list(class_dir.glob('*'))

    shuffle(images)
    total_images = len(images)
    train_count = int(total_images * 0.85)
    test_count = int(total_images * 0.14)
    val_count = total_images - train_count - test_count  # 剩余的分配给验证集

    train_images = images[:train_count]
    test_images = images[train_count:train_count + test_count]
    val_images = images[train_count + test_count:]

    (train_dir / class_dir.name).mkdir(exist_ok=True)
    (test_dir / class_dir.name).mkdir(exist_ok=True)
    (val_dir / class_dir.name).mkdir(exist_ok=True)

    for img in train_images:
        shutil.move(str(img), str(train_dir / class_dir.name / img.name))
    for img in test_images:
        shutil.move(str(img), str(test_dir / class_dir.name / img.name))
    for img in val_images:
        shutil.move(str(img), str(val_dir / class_dir.name / img.name))

    shutil.rmtree(class_dir)

print("数据集划分完成!")

最后开始分类训练:

from ultralytics import YOLO

# Load a model
model = YOLO("yolov8n-cls.yaml")  # build a new model from YAML
model = YOLO("yolov8n-cls.pt")  # load a pretrained model (recommended for training)
model = YOLO("yolov8n-cls.yaml").load("yolov8n-cls.pt")  # build from YAML and transfer weights

# Train the model
results = model.train(data="mnist160", epochs=100, imgsz=64)

分类训练没有标签,直接根据文件夹来的,所有是没有yaml文件和标签文件的。他会自动识别你的所有种类进行训练。

训练结果还不错:

image-20240531164200826

image-20240531163817561

三、孪生训练

看了下时间快下班了,大家可以参考一下这个

https://github.com/bubbliiiing/Siamese-pytorch

https://github.com/MgArcher/Text_select_captcha

下面是复制的:


问题拆解

对于点选式验证码的问题,我们可以将其拆解为两个小问题:

1、确定需要点击的字的数量和位置: 对于点选式验证码,准确识别和定位需要点击的字的数量和位置是解决问题的关键。 其中,一种常见的目标检测算法是 YOLO,通过标注数据集和训练模型,可以实现对需要点击的字进行准确识别和定位。本项目采用的是 yolov5 模型,该模型在目标检测方面表现出色,具有高速和较高的准确性。

2、对点击的字进行排序: 在确定出需要点击的字的位置后,需要按照一定的规则对这些字进行排序。采用传统的方案是通过识别图片中的文字,然后按照文字位置进行排序,但这种方法训练困难。因此,本项目采用了图片匹配模型,使用 Siamese 孪生网络对需要点击的字与预先准备好的字库中的字进行匹配,找到最佳匹配的字,并按照一定的规则进行排序。Siamese 孪生网络在图像匹配方面表现优异,能够有效地提高排序的准确性和稳定性。

  • 部分训练集

    百度网盘链接:https://pan.baidu.com/s/1IYfxVpanXyqVQ8ZFVOskrg 提取码:sp97

  • 训练模型

训练代码在下方参考文档中

yolov5训练过程:

训练流程一般包括如下几个步骤:获取训练数据集、数据预处理、模型选择、设置损失函数、反向传播和更新权值等。

对于 YOLO 模型的训练流程,可以参考下方参考文档中的文档。基本流程是,首先下载训练数据集,数据集应该包含带有标注的图像和对应的标注数据。然后使用标注工具对图像进行标注,标注工具可以在 GitHub 上找到。标注的数据应该包括目标的类别和位置信息。

img

yolo标注结果

如图所示,可以对背景图中的文字进行 char 类别的标注,对需要检测的文字进行 target 类别的标注。在训练时,模型会学习如何从图像中定位和识别目标文本。

接下来是选择合适的模型。YOLO 系列模型有多个版本,可以根据不同的需求选择适合的版本。选择好模型后,需要设置损失函数和训练参数,进行模型训练。在训练过程中,需要采用反向传播算法计算损失函数的梯度,并更新权值,以提高模型的预测准确度。本项目使用的预训练模型是yolov5s6

训练结束后,可以将模型保存成 ONNX 格式,以便在推理时进行加载和使用。

img

yolo检测结果

Siamese训练过程:

在使用孪生网络进行图像检索任务的训练前,需要对数据集进行准备。与其他模型不同,孪生网络的训练需要用到正负样本对,因此需要对数据集中的每张图像都生成一些与之匹配和不匹配的样本对。

具体实现时,一般采用已经训练好的检测模型来生成样本对。

具体操作流程如下:首先,使用检测模型对数据集中的图像进行检测,截取出每个目标的图像片段;然后,把该图像片段分别与数据集中的其他目标进行匹配和不匹配的组合,形成匹配和不匹配的样本对;最后,根据样本对的匹配情况对其进行标注,将匹配和不匹配的样本对分别放到不同的文件夹中,按照类别和顺序标注好,方便后续使用。

如下图所示,每张图像都会对应一个匹配和不匹配的样本对,每个样本对包含两张图像,分别作为孪生网络的输入。

img

孪生网络标注结果

训练数据准备好后,具体训练过程可参考下方参考文档中的文档。

同样的,训练结束后,可以将模型保存成 ONNX 格式,以便在推理时进行加载和使用。

img img img img

孪生网络标注结果

如图所示,孪生网络输出的结果可以给出背景图中的目标与右下角的目标最相似的结果,而左下角的目标则可以通过按照左坐标进行排序来得到。由此,可以方便地得到背景图中所有目标的顺序。

  • 推理部署

推理部署过程是将 YOLO 和 Siamese 模型都转换为 ONNX 模型,以便在 CPU 上使用模型,并提高部署难度和运行速度。通过模型转换,可以将模型从原有的深度学习框架中的特定格式转换成 ONNX 格式,使得模型可以在多个平台上使用,并且可以在不同的编程语言之间轻松交互。

onnx介绍:

  ONNX,即开放神经网络交换格式(Open Neural Network Exchange),是一个可以让不同深度学习框架之间互相转换和
使用模型的开放标准。它由 Facebook 和 Microsoft 共同开发,旨在为深度学习模型的部署和迁移提供更加方便和灵活的解决方案。
ONNX 支持包括 PyTorch、TensorFlow、CNTK 和 MXNet 等在内的多个深度学习框架,可以将这些框架训练出的模型转换成
ONNX 格式,从而可以被其他框架或应用所使用。

ONNX 的主要优点包括:

互操作性好:ONNX 支持多个深度学习框架之间的模型转换,使得它们可以互相使用和部署,从而减少了开发和部署的难度和成本;

高效性能:ONNX 可以在多种硬件和软件平台上运行,并提供了 C++和 Python 接口,可以大幅提高模型执行的效率和速度;

易于扩展:ONNX 的架构简单清晰,可以轻松地添加新的层次和类型,方便应对不断升级变化的深度学习技术和需求。

总之,ONNX 是一个方便快捷的深度学习模型转换和交换标准,可以帮助开发者更加轻松地将深度学习模型进行部署和迁移。

在将模型转换为 ONNX 格式后,对代码进行编译也是必不可少的一步。通过编译,可以将 Python 代码转换成机器语言代码,进一步提高模型的运行效率和速度。同时,也可以减少代码的存储空间,使得模型能够更快地在 CPU 上加载和运行。

四、搭建部署自己的接口

编写docker一键部署,有需要可联系我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/664989.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

冯喜运:5.31晚间黄金原油行情还会跌吗?独家操作策略建议

【黄金消息面分析】&#xff1a;在金融市场的波动中&#xff0c;黄金作为传统的避险资产&#xff0c;其价格走势一直受到投资者的密切关注。周五(5月31日)&#xff0c;现货黄金小幅波动&#xff0c;目前稳定在2340美元关口上方。美国核心PCE通胀数据作为美联储的首选通胀指标&a…

【力扣】LCR 130. 衣橱整理

一、题目描述 二、算法思路 这是⼀道非常典型的「搜索」类问题。 我们可以通过「深搜」或者「宽搜」&#xff0c;从 [0, 0] 点出发&#xff0c;按照题目的要求&#xff08;选择 向右移动一格 或 向下移动一格&#xff0c;但不能移动到衣柜之外 &#xff09;一直往 [m - 1, …

Nuxt3项目实现 OG:Image

目录 前言 1、安装 2、设置网站 URL 3、启用 Nuxt DevTools 4、创建您的第一个Og:Image a. 定义OG镜像 b. 查看您的Og:Image 5、自定义NuxtSeo模板 a. 定义 NuxtSeo模板 b. 使用其他可用的社区模板 6、创建自己的模板 a. 定义组件 BlogPost.vue b. 使用新模板 c.…

Tuxera Ntfs For Mac 2023的具体使用方法

大家都知道由于操作系统的原因&#xff0c;在苹果电脑上不能够读写NTFS磁盘&#xff0c;但是&#xff0c;今天小编带来的这款tuxera ntfs 2024 mac 破解版&#xff0c;完美的解决了这个问题。这是一款在macOS平台上使用的磁盘读写软件&#xff0c;能够实现苹果Mac OS X系统读写…

视频汇聚EasyCVR平台GA/T 1400视图库应用:助力社会治安防控效能提升

在信息化、智能化的时代浪潮下&#xff0c;公安视频图像信息应用系统的发展与应用显得尤为重要。GA/T 1400标准&#xff0c;全称为《公安视频图像信息应用系统》&#xff0c;作为公安行业的一项重要标准&#xff0c;其视图库的应用在提升公安工作效能、加强社会治安防控等方面发…

数据结构 | 二叉树(基本概念、性质、遍历、C代码实现)

1.树的基本概念 树是一种 非线性 的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff0c;称为根…

社交媒体数据恢复:云信Demo

一、准备工作 登录您的网易云信demo账号&#xff0c;确保您具有管理员权限。 确认您要恢复的数据类型&#xff0c;例如聊天记录、文件传输记录等。 确保您熟悉网易云信demo的后台管理界面和功能。 二、数据备份 在进行数据恢复之前&#xff0c;请先备份您现有的数据&#…

python移动文件

测试1(直接把B文件夹移动到了A里&#xff0c;成为了A的子文件夹) import os import shutil# 移动文件夹,B文件夹在当前目录没有了&#xff0c;跑到了A的子文件里 ## shutil.move(./example1/B/, ./example1/A/)测试2(B文件不动&#xff0c;将B文件里的所有的子文件夹移动到A内…

DuDuTalk:营业厅智能质检终端在通信运营商线下营业厅应用价值

在通信行业日益竞争的今天&#xff0c;线下营业厅网点是企业与客户互动的黄金触点&#xff0c;但由于缺乏有效管控和人员能力素质的层次不齐&#xff0c;如何提升线下营业厅的服务质量、提高运营效率&#xff0c;成为各大通信运营商亟待解决的问题。 在此背景下&#xff0c;我…

深入理解路由与视图函数绑定:从装饰器到Flask实战

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;装饰器在路由绑定中的应用 二、Flask中的add_url_rule()方法 示例代码…

优思学院|作为质量工程师,需要考哪些证书?别浪费你的气力,一张就够!

质量工程师做什么呢&#xff1f;他们的主要任务就是确保产品和服务的质量&#xff0c;以满足客户需求并超越竞争对手。尽管市场上有各种各样的质量管理认证&#xff0c;但优思学院认为&#xff0c;专注于六西格玛的学习和认证就足够了。 为什么选择六西格玛&#xff1f; 第一…

Unity 实现让物体渲染在最前面

演示 实现方案 1.创建一个shader脚本 2.删掉原来的内容&#xff1a;我们自己写 附上完整的shader代码&#xff1a; Shader "Custom/ZTestAlways" {Properties {_Color ("Color Tint",Color) (1,1,1,1)_MainTex("Main Tex",2D) "white&q…

obsidian zotero 联动方案 配置记录 by ZotLit Zotero style

前言 Obsidian 和 zotero 都是非常好用的开源软件&#xff0c;两个软件能做到无缝联动也是很多人的想法&#xff0c;文献笔记可以丝滑的放进 obsidian 中&#xff0c;那多好&#xff0c;网上有很多教程&#xff0c;但能够一步到位讲清楚的很少。我也踩了很多坑才完成部署&…

网络四层、七层协议

一、OSI七层模型 物理层&#xff1a;建立、维护、断开物理连接。 数据链路层&#xff1a;逻辑连接、寻找硬件地址——地址解析协议&#xff1a;ARP、PARP 反向地址转换协议 网络层&#xff1a;寻找逻辑地址&#xff0c;实现不同网络之间的路径选择——ICMP(互联网控制信息协议…

【开源】渔具租赁系统 JAVA+Vue.js+SpringBoot+MySQL

目录 一、项目介绍 1.1渔具档案模块 1.2渔具租赁模块 1.3渔具归还模块 1.4在线留言模块 二、项目截图 三、核心代码 一、项目介绍 Vue.jsSpringBoot前后端分离新手入门项目《渔具租赁系统》&#xff0c;包括渔具档案模块、渔具租赁模块、渔具归还模块、在线留言模块和部…

西藏大学计科改考11408!西藏大学计算机考研考情分析!

西藏大学&#xff08;Tibet University&#xff09;&#xff0c;简称藏大&#xff0c;是西藏自治区所属的综合性大学&#xff0c;是列入教育部直属高校序列的教育部与西藏自治区人民政府合建高校&#xff0c;国家“211工程”重点建设大学&#xff0c;国家“双一流”世界一流学科…

小角楼是怎样成为清廷御酒的?

执笔 | 扬 灵 编辑 | 古利特 “酒史千年远&#xff0c;酒花百代香&#xff0c;天府多佳酿&#xff0c;美酒驻平昌。” 对四川省巴中市平昌县而言&#xff0c;白酒是经济发展的重要产业之一&#xff0c;好山好水出好酒&#xff0c;优良的地质、水源、气候、土壤等条件以及悠久…

设计模式22——备忘录模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 备忘录模式&#xff08;Mement…

LeetCode739:每日温度

题目描述 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 解题思想 使用单…

17-java网络编程

目录 第17章 网络编程 17.1 软件结构 17.2 网络通信三要素 17.2.1 IP地址和域名 1、IP地址 2、域名 17.2.2 端口号 17.2.3 网络通信协议 17.3 TCP与UDP协议 17.3.1 UDP协议 17.3.2 TCP协议 1、三次握手 2、四次挥手 17.4 网络编程API 17.4.1 InetAddress类 17.4…