毕业设计-基于机器视觉的手写字识别系统

news2024/11/16 13:32:41

目录

前言

课题背景和意义

实现技术思路

实现效果图样例


前言


    📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投入到更重要的就业和考试中去,学长分享优质的选题经验和毕设项目与技术思路。

🚀对毕设有任何疑问都可以问学长哦!

大家好,这里是海浪学长毕设专题,本次分享的课题是

🎯基于机器视觉的手写字识别系统

课题背景和意义

本文是属于手写体文字识别应用,旨在基于MindSpore AI计算框架和Atlas实现手写汉字拍照识别系统。该系统能够对写在纸上的多个汉字,使用摄像头拍摄视频,实时检测字符区域并给出识别类别。该系统包括手写汉字模型训练(云上)、模型转换、模型部署、摄像头图像采集、模型推理(端侧)、结果展示等完整训练和应用流程。其中模型采用的是深度神经网络,目前深度学习在文字识别方面有着广泛的应用,多分类问题是其中重要的一类。然而,深层网络模型的结构通常很复杂,对于一般的多类别分类任务,所需的深度网络参数通常随着类别数量的增加而呈现超线性增长。本文需要识别字库中字的类别数高达3755类,模型训练是整个流程中耗时最长且决定识别精度的重要环节,模型推理在识别流程中占据较大部分。所以这两个环节的速度和精度对于用户体验至关重要。如何研究高性能、高精度、实用性强的方案变得极具挑战性。

实现技术思路

准备数据集

1、数据集的下载与导入

由于识别手写数字这个任务相对于拟合正弦函数而言复杂一些,所以需要的数据量比较大,因此,我们采用现成的手写数字数据集MINST。这个数据集里包括了70000张28×28的灰度图片,其中训练数据60000张,测试数据10000张,每张图片都是一个手写数字。

构建神经网络模型

这一次我们要使用CNN(卷积神经网络)模型。我们不妨先来看一下卷积层中发生了什么。

 首先我们有一张图片和一个卷积核 [ 一般其大小(kernel_size)为3×3或5×5 ] ,这个卷积核会遍历这张图片,在遍历的过程中,卷积核上的数字会与图片上对应位置的像素相乘、求和,最后把这个数字写在一张新的图片里的对应位置,这就完成了一次卷积(Convolution)。而这一层的反向传播就是调整卷积核内的数字的过程。

当然,一个卷积层中也不止一个卷积核,而是有多个卷积核同时工作,提取出不同的特征以供后面的层继续操作。

不过这样“卷积”一次以后,图片就缩小了一圈,所以我们一般会在原图片的周围加一圈空白像素(padding)来确保卷积的结果与原图片大小相等。


from keras.models import Model
from keras.layers import Input, Dropout, Reshape, Activation, Flatten, Dense
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.initializers import orthogonal, constant, he_normal
from keras.regularizers import l2
from keras import backend as K
from keras.layers.normalization import BatchNormalization
from keras.layers.advanced_activations import PReLU
import config
# 这个是ReLU6,在原ReLU上加上一个约束(大于6的都变为6,这样就可以防止梯度爆炸)
def relu6(x):
    """Relu 6
    """
    return K.relu(x, max_value=6.0)

def net():
    inputs = Input(shape=(config.IMAGE_SIZE, config.IMAGE_SIZE, config.NUM_CHANNELS))
    x = Conv2D(config.FILTER_NUM[0], (1, 3), padding='same', kernel_initializer=he_normal())(inputs)
    x = Conv2D(config.FILTER_NUM[0], (3, 1), padding='same', kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(x)

    x = Conv2D(config.FILTER_NUM[1], (1, 3), padding='same', kernel_initializer=he_normal())(x)
    x = Conv2D(config.FILTER_NUM[1], (3, 1), padding='same', kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(x)

    x = Conv2D(config.FILTER_NUM[2], (1, 3), padding='same', kernel_initializer=he_normal())(x)
    x = Conv2D(config.FILTER_NUM[2], (3, 1), padding='same', kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(x)

    x = Conv2D(config.FILTER_NUM[3], (1, 3), padding='same', kernel_initializer=he_normal())(x)
    x = Conv2D(config.FILTER_NUM[3], (3, 1), padding='same', kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = Conv2D(config.FILTER_NUM[4], (1, 3), padding='same', kernel_initializer=he_normal())(x)
    x = Conv2D(config.FILTER_NUM[4], (3, 1), padding='same', kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(x)

    x = Conv2D(config.FILTER_NUM[5], (1, 3), padding='same', kernel_initializer=he_normal())(x)
    x = Conv2D(config.FILTER_NUM[5], (3, 1), padding='same', kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = Conv2D(config.FILTER_NUM[6], (1, 3), padding='same', kernel_initializer=he_normal())(x)
    x = Conv2D(config.FILTER_NUM[6], (3, 1), padding='same', kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(x)

    x = Flatten()(x)
    x = Dense(config.FILTER_NUM[7], kernel_regularizer=l2(0.005), kernel_initializer=he_normal())(x)
    x = BatchNormalization()(x)
    # x = Activation(relu6)(x)
    x = PReLU()(x)
    x = Dropout(0.5)(x)

    y = Dense(config.NUM_LABELS, activation='softmax', kernel_initializer=he_normal())(x)
    model = Model(inputs=inputs, outputs=y)
    return model

准备损失函数和优化器

之前我们用的是MSE(均方误差)损失函数,这次我们也可以继续使用MSE,但我们有一个更好的选择——交叉熵损失函数。

交叉熵是统计学中的一个概念,用于衡量两个概率分布的差异性,而我们下神经网络输出的十个数字刚好可以看作一个概率分布。这样,利用交叉熵就可以很容易的衡量出当前的输出与目标输出的差距是多少。

我们可以直接使用pytorch内置的交叉熵损失函数

接下来就是选择优化器,我们仍然选择SGD优化器

现在神经网络的一切已经准备就绪了。

训练神经网络

训练神经网络的过程分为训练和测试两部分

训练结果的保存与读取

pytorch已经为我们提供了保存和读取神经网络参数的函数,我们只需要调用即可。

首先是在训练结束后把训练好的网络保存起来,在上面的训练代码后面填上下面这句即可。

 模型定义完成,就可以进行训练了,数据读取还是采用迭代的方式,用多少读多少,不然一下子全部读进内存内存不够,有近100w张图片。

实现效果图样例

 

我是海浪学长,创作不易,欢迎点赞、关注、收藏、留言。

毕设帮助,疑难解答,欢迎打扰!

最后

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

变焦镜头内参数如何获得?

很多时候,我们是使用相应的棋盘格标定进行相机内参数的获取,但是对于相机而言,如果要是焦距范围是测量比较远的物体,那么我们要进行注意相应的内参数就是不能够使用棋盘格标定法进行获取,因为不准. 由于项目的需要,这里我就是需要进行探究一下,如何通过自己调试直接设定内参数…

CSS 实现卡片边框渐变动画

前言 &#x1f44f;CSS实现卡片边框渐变动画&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 父容器添加背景渐变色 <div class"card"></div>.card {background: linear-gradient(0deg, …

Tensorboader图片和模型可视化

非常简单&#xff0c;10分钟搞懂1 Tensorboader介绍2 进行写入和运行&#xff08;共2步&#xff09;3 图像显示3.1 显示图片3.2 显示模型3.3 动态显示学习率等参考文献1 Tensorboader介绍 它就是1个可视化工具&#xff0c;需要用pip进行下载&#xff1b; 下载以后进行显示&a…

SpringCloud框架(三):微服务优化,Feign的最佳实现方案

SpringCloud环境搭建&#xff1a;生产和消费 RestTemplate Spring章节复习已经过去&#xff0c;新的章节SpringCloud开始了&#xff0c;这个章节中将会回顾微服务相关 主要依照以下几个原则 每一个组件的Demo和Coding上传到我的代码仓库在原有基础上加入一些设计模式&#xf…

数据结构与算法之图的应用

一.树之习题选讲-Tree Traversals Again 树习题-TTA.1 题意理解 非递归中序遍历的过程 1. Push的顺序为先序遍历(pre)2. Pop的顺序给出中序遍历(in) 树习题-TTA.2 核心算法 上图分别是先序、中序、后序遍历通过规律我们可以看到他们之间的位置分配 //伪代码 void solve(int …

Zabbix在X86服务器上的部署流程

服务器资源:Centos7、X86架构 部署zabbix服务端 #设置SELinux 成为permissive模式临时关闭selinux防火墙 setenforce 0 #获取zabbix的下载源和更换阿里源 https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm #解压zabbix包 …

探花交友_第4章_MongoDB基础(新版)

探花交友_探花交友_第4章_MongoDB基础(新版) 文章目录探花交友_探花交友_第4章_MongoDB基础(新版)课程介绍1. 通用设置1.1 需求分析1.1.1 需求分析1.1.2 数据库表1.1.3 实体类SettingsQuestionBlackList1.2 查询通用设置1.2.1 接口文档1.2.2 代码实现vo对象tanhua-app-serverSe…

易知微11月更新速递 | 预案集如何实现“一屏多端”联动指挥体系

伴随着“2022Easy Future秋季产品发布会”的举行&#xff0c;易知微也迎来了EasyV6.0的全新升级&#xff0c;通过新产品、新服务&#xff0c;助力实现一个能“数智视融合&#xff0c;虚实人联动”的数字增强世界。近一个月我们依旧奋力于产品迭代优化&#xff0c;又给大家带来了…

留学生Paper写作怎么进行深度解析?

对于留学生Paper而言&#xff0c;要想文章显得井井有条&#xff0c;逻辑结构在这个时候就显得很重要&#xff01;为什么这样说呢&#xff1f;首先我们要认识到一点&#xff0c;就是Paper必须做到内容和形式上统一。内容就是文章的主题和材料&#xff0c;形式是指逻辑结构和语言…

视觉小目标检测论文速读

视觉小目标检测论文速读 本文主要针对三篇文章典型文章。 一. SuperYOLO Super Resolution Assisted Object Detection in Multimodal Remote Sensing Imagery 1. 主要工作: 首先去掉Focus模块取保持HR特征, 避免分辨率下降&#xff0c;有效克服小目标空间损失的减少。利…

(一) SpringCloud+Security+Oauth2微服务授权初步认识

一 引言 再前面的security专题中 我们学习了单体架构基于SpringSecurity实现的授权方案,这种在业务量较小及业务的复杂度较低时比较实用,随着业务的复杂度越来越高,微服务架构也越来越被更多的公司使用&#xff0c;本文就微服务中的主流授权方案及oauth2中基本概念做简要概述。…

厨神之蛋糕制作

失败了7次&#xff0c;成功了6次。成功的6次里有好有坏&#xff0c;总结一下蛋糕制作的过程与要点。 原料 低筋面粉&#xff08;筋度越高越偏向包子馒头的口感&#xff0c;松软度越低&#xff09;、白糖、鸡蛋、水&#xff08;也可以用牛奶或其他含水的物质&#xff09;、食用…

多目slam论文阅读系列一:MULTICOL-SLAM论文阅读

论文地址&#xff1a;https://arxiv.org/pdf/1610.07336.pdf 代码&#xff1a;GitHub - urbste/MultiCol-SLAM: This repository contains a multi-fisheye camera SLAM. The underlying SLAM system is based on ORB-SLAM.参考文档&#xff1a;【算法】跑MultiCol-SLAM遇到的效…

Java小区物业管理系统源码带本地搭建教程

技术架构 技术框架&#xff1a;springboot mybatis thymeleaf Mysql5.7 运行环境&#xff1a;jdk8 IntelliJ IDEA maven 宝塔面板 本地搭建教程 1.下载源码&#xff0c;本地电脑新建一个数据库&#xff0c;导入wuye.sql文件至数据库中。 2.使用IDEA打开wuyeadmin目录&…

web随想笔记

1 OJ大概架构 1.0 OJ页面–>WEB服务器&#xff08;SpringBoot&#xff09;–>判题机(Linux) OJ页面将提交的代码封装成json格式发给web服务器端&#xff0c;服务器端接收json获取信息&#xff0c;进行进一步封装&#xff0c;转发给判题机&#xff0c;拆解json数据获得程…

擦除编码(EC)数据中心中的最优机架协调更新

擦除编码EC在数据中心中的最优机架协调更新介绍与背景工作文章外主流的工作文章摘要RackCU, the optimal Rack-Coordinated Update solution数据增量基础更新奇偶校验基础更新RackCU其他的更新方法一些数值实验可以仅需改进的地方参考文献介绍与背景工作 擦除编码&#xff08;…

Simulink建模:CRC校验模型

本文研究CRC校验的Simulink模型及其代码生成。 文章目录1 CRC校验2 C代码形式3 Matlab/Simulink建模及代码生成3.1 Matlab Function建模3.2 For Iteration子系统建模4 总结与思考1 CRC校验 在汽车软件开发中&#xff0c;CRC校验常用于CAN通信中。通常将某个CAN报文中的数据通过…

【AVL树】

目录基础知识AVL树的定义结点的平衡因子结构体部分操作思路AVL树的插入平衡化旋转左单旋转右单旋转先左后右双旋转先右后左双旋转插入函数AVl树的删除左平衡代码右平衡代码删除函数基础知识 AVL树的定义 一棵AVL树或者是空树&#xff0c;或者是具有谢下列性质的二叉搜索树&am…

Docker 实战——部署 Nginx 镜像容器、Tomcat 镜像容器、MySQL 镜像容器

3.安装 Docker 可使用 yum list docker-ce --showduplicates | sort -r 命令来查看 Docker 的所有版本。 [rootDocker ~]# yum -y install docker-ce-17.12.1.ce #安装docker 4.启动 Docker 并设置开机自启 [rootDocker ~]# systemctl start docker [rootDocker ~]# syste…

uniClound云开发创建流程

uniClound是 DCloud 联合阿里云、腾讯云&#xff0c;为开发者提供的基于 serverless 模式和 js 编程的云开发平台。云服务创建项目&#xff0c;使用熟悉的js&#xff0c;轻松搞定前后台整体业务&#xff0c;使前端开发离全栈开发又进一步&#xff0c;尤其是一键生成代码的功能&…