当前位置: 首页 > news >正文

构建智能手写数字和符号识别系统:深度学习与YOLO模型的结合

深度学习技术在计算机视觉领域的应用日益广泛,手写数字和符号的自动识别在教育、金融、邮政等领域具有重要意义。本博客将系统地介绍如何构建一个基于YOLO模型的手写数字和符号识别系统,涵盖数据准备、模型训练、UI界面开发和部署。

一、引言
项目背景与意义

手写数字和符号的自动识别系统可以大大提高信息处理的效率,减少人工录入的错误率。利用深度学习技术,尤其是YOLO(You Only Look Once)目标检测模型,可以实现对手写字符的高效、准确识别。

目标
  • 构建一个基于YOLO的深度学习模型,能够准确识别手写数字和符号
  • 开发一个用户友好的Web界面,方便用户上传图片并获取识别结果
  • 部署系统,实现实时在线识别
二、技术方案
开发环境
  • 操作系统:Windows/Linux/MacOS
  • 编程语言:Python 3.8+
  • 开发工具:PyCharm/VSCode
  • 深度学习框架:PyTorch
  • Web框架:Flask
依赖库安装

首先,创建一个新的Python虚拟环境并安装所需的依赖库:

conda create -n handwriting_recognition python=3.8
conda activate handwriting_recognition
pip install torch torchvision torchaudio
pip install flask opencv-python pandas
pip install -U git+https://github.com/ultralytics/yolov5
三、数据准备
数据集获取

使用公开的手写数字和符号数据集,如MNIST和Kuzushiji-MNIST。可以从以下链接下载:

  • MNIST: http://yann.lecun.com/exdb/mnist/
  • Kuzushiji-MNIST: https://github.com/rois-codh/kmnist
数据预处理

将数据集转换为YOLO格式,需要包含图像文件和相应的标签文件。标签文件格式如下:

<class_id> <x_center> <y_center> <width> <height>

编写数据预处理脚本,将数据集转换为YOLO格式:

import os
import pandas as pd
from PIL import Imagedef convert_to_yolo_format(df, output_dir):for index, row in df.iterrows():img = Image.open(row['image_path'])width, height = img.sizex_center = (row['x_min'] + row['x_max']) / 2 / widthy_center = (row['y_min'] + row['y_max']) / 2 / heightw = (row['x_max'] - row['x_min']) / widthh = (row['y_max'] - row['y_min']) / heightlabel_path = os.path.join(output_dir, f"{row['image_id']}.txt")with open(label_path, 'w') as f:f.write(f"{row['class_id']} {x_center} {y_center} {w} {h}\n")# Example usage
# df = pd.read_csv('annotations.csv')  # Assuming annotations.csv has columns: image_id, image_path, x_min, y_min, x_max, y_max, class_id
# convert_to_yolo_format(df, 'labels/')
数据集划分

将数据集划分为训练集、验证集和测试集:

import shutil
import randomdef split_dataset(source_dir, train_dir, val_dir, test_dir, train_ratio=0.7, val_ratio=0.2):all_files = os.listdir(source_dir)random.shuffle(all_files)train_count = int(len(all_files) * train_ratio)val_count = int(len(all_files) * val_ratio)for i, file in enumerate(all_files):if i < train_count:shutil.move(os.path.join(source_dir, file), train_dir)elif i < train_count + val_count:shutil.move(os.path.join(source_dir, file), val_dir)else:shutil.move(os.path.join(source_dir, file), test_dir)split_dataset('data/images', 'data/train/images', 'data/val/images', 'data/test/images')
split_dataset('data/labels', 'data/train/labels', 'data/val/labels', 'data/test/labels')
四、模型训练
配置YOLO模型

下载YOLOv5预训练权重,并配置数据文件:

# handwrite.yaml
train: data/train
val: data/val
nc: 10  # number of classes (0-9 for MNIST, adjust accordingly for symbols)
names: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
模型训练

运行以下命令开始训练:

python train.py --img 640 --batch 16 --epochs 50 --data handwrite.yaml --cfg yolov5s.yaml --weights yolov5s.pt
模型评估

使用验证集评估模型性能,并进行必要的超参数调优:

from sklearn.metrics import accuracy_score, recall_score, f1_scorey_true = [...]  # true labels
y_pred = [...]  # predicted labelsaccuracy = accuracy_score(y_true, y_pred)
recall = recall_score(y_true, y_pred, average='macro')
f1 = f1_score(y_true, y_pred, average='macro')print(f"Accuracy: {accuracy}, Recall: {recall}, F1 Score: {f1}")
五、UI界面开发
Flask搭建Web应用
  1. 创建项目目录结构:

    handwriting_recognition/
    ├── app.py
    ├── templates/
    │   ├── index.html
    │   └── result.html
    ├── static/
    │   └── uploads/
    └── models/└── yolov5s.pt
    
  2. 编写网页模板:

    • index.html

      <!DOCTYPE html>
      <html lang="en">
      <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Handwriting Recognition</title><link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
      </head>
      <body><h1>Handwriting Recognition</h1><form action="/predict" method="post" enctype="multipart/form-data"><input type="file" name="file"><button type="submit">Upload</button></form>
      </body>
      </html>
      
    • result.html

      <!DOCTYPE html>
      <html lang="en">
      <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Result</title><link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
      </head>
      <body><h1>Detection Result</h1><img src="{{ url_for('static', filename='uploads/' + filename) }}" alt="Uploaded Image"><p>{{ result }}</p>
      </body>
      </html>
      
实现后端逻辑
  • app.py
    from flask import Flask, request, render_template, url_for
    import os
    from werkzeug.utils import secure_filename
    import torch
    from PIL import Imageapp = Flask(__name__)
    app.config['UPLOAD_FOLDER'] = 'static/uploads/'model = torch.hub.load('ultralytics/yolov5', 'custom', path='models/yolov5s.pt')@app.route('/')
    def index():return render_template('index.html')@app.route('/predict', methods=['POST'])
    def predict():if 'file' not in request.files:return 'No file part'file = request.files['file']if file.filename == '':return 'No selected file'if file:filename = secure_filename(file.filename)filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)file.save(filepath)img = Image.open(filepath)results = model(img)results.save(save_dir=app.config['UPLOAD_FOLDER'])return render_template('result.html', filename=filename, result=results.pandas().xyxy[0].to_json(orient="records"))if __name__ == '__main__':app.run(debug=True)
    
六、模型部署
部署到云服务器
  1. 使用Gunicorn部署
    pip install gunicorn
    gunicorn -w 4 app

:app


2. **配置Nginx反向代理**
```nginx
server {listen 80;server_name your_domain;location / {proxy_pass http://127.0.0.1:8000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}
七、声明

声明:本文只是简单的项目思路,如有部署的想法,想要(UI界面+YOLOv8/v7/v6/v5代码+训练数据集+视频教学)的可以联系作者.

相关文章:

  • springboot集成canal
  • Windows系统使用内网穿透配置Mysql公网地址实现IDEA远程连接
  • 【持续监控与反馈】DevOps中的监控与反馈机制
  • TypeScript 装饰器详解
  • 大模型是否潜在地进行多跳推理?
  • 51 for 循环与 while 循环
  • OpenShift 4 - 用 oc-mirror 为离线 OpenShift 集群的 Mirror Registry 同步容器镜像
  • 使用npm全局安装typescript
  • Java 并发编程:一文了解 synchronized 的使用
  • JMeter接口测试-5.JMeter高级使用
  • 大模型学习笔记 - InstructGPT中的微调与对齐
  • AI测试入门:认识RAG(检索增强生成)
  • pip‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  • Unity 资源之 Break Items - Toon VFX破碎物品与卡通硬币动画分享
  • 码蹄集部分题目(2024OJ赛7.31-8.4;树状数组+并查集)
  • SegmentFault for Android 3.0 发布
  • 收藏网友的 源程序下载网
  • [ JavaScript ] 数据结构与算法 —— 链表
  • “大数据应用场景”之隔壁老王(连载四)
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  •  D - 粉碎叛乱F - 其他起义
  • Docker 笔记(2):Dockerfile
  • Java 多线程编程之:notify 和 wait 用法
  • mysql 5.6 原生Online DDL解析
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • 彻底搞懂浏览器Event-loop
  • 聊聊flink的BlobWriter
  • 浅谈Golang中select的用法
  • 删除表内多余的重复数据
  • 在Unity中实现一个简单的消息管理器
  • 怎么将电脑中的声音录制成WAV格式
  • ​VRRP 虚拟路由冗余协议(华为)
  • !!Dom4j 学习笔记
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (pojstep1.1.2)2654(直叙式模拟)
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (二)学习JVM —— 垃圾回收机制
  • (七)glDrawArry绘制
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (五)IO流之ByteArrayInput/OutputStream
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转) ns2/nam与nam实现相关的文件
  • (转)http协议
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .NET BackgroundWorker
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .Net小白的大学四年,内含面经
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • ::什么意思
  • @AliasFor 使用