基于神经网络的手写汉字提取与书写评分系统研究

相关源码和文档获取请私聊QQ:3106089953

论文目录结构

目 录
摘 要 I
Abstract II
目 录 IV
第1章 绪论 1
1.1. 研究背景与意义 1
1.2. 国内外研究现状 2
1.2.1. 文本定位技术研究现状 2
1.2.2. 手写汉字识别研究现状 3
1.2.3. 汉字书写质量评价方法研究现状 4
1.3. 本文所做工作 4
1.4. 论文结构安排 5
第2章 系统需求分析及概要设计 6
2.1. 可行性分析 6
2.2. 系统用例分析 7
2.2.1. 用例表设计 7
2.3. 功能需求分析 9
2.4. 性能需求分析 10
2.5. 系统总体设计 10
2.5.1. 系统总体架构设计 10
2.5.2. 系统功能模块设计 12
2.6. 相关技术介绍 13
2.6.1. Android系统 13
2.6.2. OpenCV视觉库 14
2.6.3. TensorFlow开源库 14
2.7. 本章小结 14
第3章 系统详细设计及实现 16
3.1. 系统模块详细设计 16
3.2. 笔画提取模块 16
3.2.1. 单帧图像的疑似笔画像素点检测 17
3.2.2. 基于帧差法的笔画增长点检测 19
3.2.3. 笔画切换点检测与单笔画的提取 20
3.3. 基本笔画识别模块 22
3.3.1. 汉字的基本笔画 22
3.3.2. LeNet-5网络 23
3.4. 书写评分模块 25
3.4.1. 重心特征 27
3.4.2. 网格特征 27
3.4.3. 整字综合评分 27
3.5. 系统UI界面 28
3.6. 本章小结 30
第4章 系统性能测试 31
4.1. 测试的意义与方法 31
4.2. 运行性能测试 32
4.2.1. 测试设备 32
4.2.2. 测试环境 32
4.3. 本章小结 33
总结 34

论文工作总结 34
工作展望 34
参考文献 35
致谢 37

相关目录的具体内容

2.3.功能需求分析
系统的用例分析是从用户操作的角度对系统进行设计,对于系统的功能需求分析,是以开发者的角度进行设计,即对系统的用例图及用例描述进行详细定义与描述,给开发人员作为参考。所有功能均与系统用例一一对应。
1)录制书写过程
该功能通过用户点击按钮触发,软件获取系统摄像头使用权限,开启摄像头,进行视频录制,直至用户点击按钮结束录制。输出mp4多媒体格式文件并传递给下一模块。
2)报告书写正确性
该功能触发前,需要用户输入书写的汉字,以供系统使用相应的模板特征数据与输入数据进行对比分析。系统对录制好的书写过程视频进行计算,提取出单一笔画,通过笔画识别、特征比对等方式得到书写正确性结果。书写正确性包括笔画类型、笔画位置、笔画顺序等方面的正确性。报告结果在文本框中以文本方式显示。后台给出笔画状态编码列表,前端对其映射得到对应文本。
3)显示书写改正建议
该功能依赖于报告书写正确性功能的分析结果。改正建议类型与正确性类型相对应,因此同样使用映射得到对应的建议文本,在前端的文本框中显示。
4)显示书写评分
该功能与报告书写正确性、显示书写改正建议一同显示。后台对单一笔画、整字分别通过特征比对法计算评分,最后将其权值相加以百分制形式给出用户的综合书写评分。
2.4.性能需求分析
系统的功能需求仅仅可以确定系统的任务,但是为了让系统的能够更长久且无误的运行,还需要进行系统的性能需求分析。系统的性能需求是按照系统的功能需求以及系统本身的特性所设定的。将从系统的开发、系统的运行以及部署等多个方面,进行性能的提取。当系统的性能满足需求后,系统的生命周期才会满足预估,且也会使得系统的功能更加完备。
1.可靠性
系统需要具备一定的可靠性,即用户完成视频输入后,在设备运行内存充足的情况下,系统应该在5秒内完成计算,给出反馈结果。
2.容错性
用户在进行功能操作时,若输入了错误的数据,如用户在汉字书写过程中,出现连笔、错字的情况等,用户在输入信息时输入了错误的形式信息后,系统不会自动闪退或崩溃,而是将这些错误情况进行捕捉,并显示哪里出错,让用户进行及时更改。
3.可维护性
系统需要具备一定的可维护性,随着后续的算法优化与替换,书写评价功能的增加等,所有的模块均应该是可维护的,且可增加、替换或者删除的,系统在设计过程中需要达到高内聚低耦合的状态。
2.5.系统总体设计
2.5.1.系统总体架构设计
系统总体架构设计是指按照多种角度进行分层,本系统的总体架构如图2-2所示。系统可分为访问层、前端UI、业务层、数据层及基础设施层[15]。
对于访问层,有Android移动端及安卓用户作为终端。系统的所有功能均是通过这一硬件进行数据计算与显示的。
前端UI对应系统的页面展示与用户交互,该系统部署在App端,使用Android操作系统,以PyQt5作为GUI开发框架,本文转载自http://www.biyezuopin.vip/onews.asp?id=14866需要完成对Activity的编写以及Video的读写。
系统的业务层是将系统的功能以业务逻辑的形式展示在系统的总体架构图中。对于用户,主要包含录取视频、选择汉字等业务逻辑功能。对于后台的业务逻辑主要包含视频录制模块、书写评价模块,其中视频录制模块包括录取视频,书写评价模块包括笔画提取、笔顺判别、文本定位与切割、书写评分等功能。
数据层主要包含了数据的存储过程、数据缓存、文件读写等数据操作。
基础设施层对应了系统的物理架构所需要的硬件设备,包括操作系统、摄像头、CPU等。

部分代码展示

import cv2
import sys
import numpy as np
from matplotlib import pyplot as plt
import pickle
from text_location import *

char_feat_path = './utils/character_feature_dict'
stroke_feat_path = './utils/stroke_feature_dict'

def gravity_core(img):  # 计算汉字的重心特征向量
    '''
    计算汉字的重心特征向量
    ----------
    :param img [ndarray]: 笔画二值图像,笔画为白色
    :return [list]: 归一化的重心坐标
    :return [list]: 绝对重心坐标
    '''
    h, w = img.shape
    x_axis = 0
    y_axis = 0
    total = np.sum(img[:, :])
    for row in range(h):
        y_axis += row * np.sum(img[row, :])
    Gy = y_axis / total
    for col in range(w):
        x_axis += col * np.sum(img[:, col])
    Gx = x_axis / total
   #除是进行了归一化处理,消除了输入图像分辨率的差异对评分的影响
    return [Gx/w, Gy/h], [Gx, Gy]


def grid_vector(img, n_divide = 3):   # 计算图像的网格特征向量
    '''
    计算汉字的网格特征向量
    ----------
    :param img [ndarray]: 笔画二值图像,笔画为白色
    :param n_divide [int]: 
    :return [list]: 
    '''
    w, h = img.shape
    spanX = int(w/n_divide)
    spanY = int(h/n_divide)
    grid_area = spanX * spanY
    left_border = 0
    up_border = 0

    grid_vector = []
    #求出每一个矩阵的特征值
    for row in range(n_divide):
        left_border = 0
        for col in range(n_divide):
            white_num = np.sum(img[up_border:up_border+spanY, left_border:left_border+spanX])
            #在这个矩形之中 一共有多少个方格是有白色像素的,然后除以这个矩形的面积
            grid_vector.append(white_num / grid_area)
            left_border += spanX
        up_border += spanY

    return grid_vector

def cosine_similarity(vec1, vec2):
    '''
    计算向量余弦相似度
    ----------
    :param vec1 [list]: 向量1,元素应为可计算数值
    :param vec2 [list]: 向量2,元素应为可计算数值
    :return [float]: 相似性数值,取值范围为[-1,1]
    '''
    #求余弦相似度的公式
    sim = np.dot(vec1, vec2) / (np.linalg.norm(vec1)*np.linalg.norm(vec2))
    return sim

def stroke_score(stroke_list, char_id, dict_path, gravity_ratio=0.2):
    '''
    根据单笔画分别评分
    ----------
    :param img [ndarray]: 笔画二值图像列表,笔画为白色
    :param char_id [str]: 汉字编号
    :param dict_path [str]: 模板特征字典文件路径
    :param gravity_ratio [float]: 重心特征评分所占比例,为0到1之间的值
    :return [float]: 笔画评分
    '''
    if gravity_ratio>1.0 or gravity_ratio<0:
        print("单笔画重心评分比例错误,应为0到1之间的值")
        gravity_ratio = 0.2
    grid_ratio = 1.0 - gravity_ratio
    pattern_feat = []
    score = []

    with open(dict_path, 'rb') as f:
        dict = pickle.load(f)
        pattern_feat = dict[char_id]
        if len(pattern_feat):
            if len(pattern_feat)==len(stroke_list):
                for i in range(len(pattern_feat)):  # 对每个笔画分别计算特征向量,计算评分
                    gravity, _ = gravity_core(stroke_list[i])   #重心特征
                    grid = grid_vector(stroke_list[i])              #网络特征
                    gravity_similarity = cosine_similarity(gravity, pattern_feat[i][0])
                    grid_similarity = cosine_similarity(grid, pattern_feat[i][1])

                    # test
                    print("单笔画重心评分", gravity_similarity)
                    print("单笔画网格评分", grid_similarity)
                    print()
                    # 这是笔画的评分
                    score.append(gravity_similarity * gravity_ratio + grid_similarity * grid_ratio)
                return np.mean(score)
            else:
                print("【ERROR】 笔画图片数量与模板不一致!")
                sys.exit(0)
                return -1
        else:
            print("模板数据丢失!")
            return -1
#上面是检测单个笔画的,这个是整个字的,用的方法是一模一样
def char_score(char_img, char_id, dict_path, gravity_ratio=0.2):
    '''
    对整字进行评分
    ----------
    :param img [ndarray]: 汉字二值图像,文字部分为白色
    :param char_id [str]: 汉字编号
    :param dict_path [str]: 模板特征字典文件路径
    :param gravity_ratio [float]: 重心特征评分所占比例,为0到1之间的值
    :return [float]: 整字评分
    '''
    if gravity_ratio>1.0 or gravity_ratio<0:
        print("单笔画重心评分比例错误,应为0到1之间的值")
        gravity_ratio = 0.2
    grid_ratio = 1.0 - gravity_ratio
    
    with open(dict_path, 'rb') as f:
        dict = pickle.load(f)
        pattern_feat = dict[char_id]
        if len(pattern_feat):
            gravity, _ = gravity_core(char_img)
            grid = grid_vector(char_img)
            gravity_similarity = cosine_similarity(gravity, pattern_feat[0])
            grid_similarity = cosine_similarity(grid, pattern_feat[1])
            
            # test
            print("整字重心评分", gravity_similarity)
            print("整字网格评分", grid_similarity)
            print()

            return (gravity_similarity * gravity_ratio + grid_similarity * grid_ratio)
        else:
            print("模板数据丢失!")
            return -1

def aesthetic_score(stroke_list, char_id):
    '''
    计算汉字的书写质量综合评分
    ----------
    :param stroke_list [list]: 笔画二值图像列表,笔画为白色
    :return [float]: 书写评分
    '''
    # 计算单笔画评分
    strokes_score = stroke_score(stroke_list, char_id, stroke_feat_path)
    # 计算整字评分
    char_img = img_merge(stroke_list)
    character_score = char_score(char_img, char_id, char_feat_path)

    # 权值相加得到综合评分
    stroke_ratio = 0.5
    char_ratio = 1.0 - stroke_ratio
    final_score = strokes_score * stroke_ratio + character_score * char_ratio

    return final_score

if __name__ == '__main__':
    stroke_list = []
    for i in range(4):
        img = cv2.imread("./test_video/strokes/" + str(i) + ".jpg")
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        stroke_list.append(img)
    stroke_list = text_location(stroke_list)    # 文本定位与切割

    score = aesthetic_score(stroke_list, '0750')
    print(score)

项目运行图片展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

迁移数据mysql到clickhouse

场景&#xff1a; 项目上需要将mysql表中数据迁移到clickhouse。 理论&#xff1a; 借助MaterializeMySQL 说明&#xff1a; 首先该方案实施需要启动mysql的binlog配置否则同步不了&#xff0c;尽管MaterializeMySQL官方说是在实验阶段&#xff0c;不应该在生产上使用&#x…

numpy 广播

现在有两个数组分别为&#xff1a; arr1 [0, 1, 2, 3, 4, 5, 6]arr2 [1] 这两个数组可以进行广播吗&#xff1f; 二维数组广播&#xff1a; arr1 np.arange(0,3).reshape(1,3) array([[0, 1, 2]]) arr2 np.arange(4,7).reshape(3,1) array([[4],[5],[6]])这两个数组可以进行…

电脑单机游戏推荐:嗜血印 BLOODY SPELL 中文版

《嗜血印》该游戏的故事发生在一个充满秘密和恐怖的江湖中。一伙自称为“灵虚教”的神秘组织闯入万法归宗门派&#xff0c;导致天下大乱。妹妹小鲤被掳为人质&#xff0c;同门师兄弟相继遭到毒手。当嗜血咒印打开的那一刻&#xff0c;重识自我的苏夜锦&#xff0c;为了守护自己…

【linux】Ubuntu 22.04.3 LTS截屏

一、快捷键 交互式录屏 ShiftCtrltAltR 交互式截图 Print 对窗口进行截图 AltPrint 截图 ShiftPrint 快捷键可能取决于使用的桌面环境和个人的键盘快捷键设置。如果上述快捷键不起作用&#xff0c;可能需要检查系统设置中的键盘快捷键部分&#xff0c;以了解系统中截图的…

【MATLAB源码-第105期】基于matlab的4PAM调制解调仿真,输出误码率和误符号曲线并且和理论值对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 4PAM&#xff08;4-Pulse Amplitude Modulation&#xff0c;4脉冲幅度调制&#xff09;是一种数字调制技术&#xff0c;它通过改变载波信号的幅度来表示数据。在4PAM中&#xff0c;载波的幅度可以采用四种不同的水平&#xf…

AcWing 998. 起床困难综合症

原题链接 其实上面这一堆就是想说&#xff0c;输入 n,m以及 n 个数和该数所对应的运算&#xff0c;其中运算包括有 与、或、异或 三种&#xff0c;真正的问题就是在所有不大于 m 的数&#xff08;非负数&#xff09;中&#xff0c;对给定的 n 个数都按该数所对应的运算运算一遍…

visi 各版本安装指南

visi下载链接 https://pan.baidu.com/s/1WNksdiChCPebPvRRSVakOA?pwd0531 1.鼠标右键【visi2021(64bit)】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;选择【解压到 visi2021(64bit)】。 2.打开解压后的文件夹&#xff0c;鼠标右击【Setup VISI 2…

竞赛练一练 第27期:GESP和电子学会相关题目练习

GESP一级2023.03_小猫捉老鼠 1. 准备工作 (1)导入背景Room 2; (2)删除默认小猫角色,导入角色Mouse1、Cat 2。 2. 功能实现 (1)点击绿旗,老鼠出现在随机位置; (2)通过键盘的“↑”、“↓”、“←”、“→”键来控制小猫行走,每按一次,移动5步; (3)小猫在…

GoLang:gRPC协议的介绍以及详细教程,从Protocol开始

目录 ​编辑 引言 一、安装相关Go语言库和相关工具 1. 安装Go 2. 安装Protocol Buffers Compiler 2.1 Windows 2.1.1 下载 2.1.2 解压 2.1.3 环境变量 2. macOS 3. Linux 4. 验证安装 3. 安装gRPC-Go 4. 安装Protocol Buffers的Go插件 二、定义服务 三、生成Go…

论文笔记 Understanding Electricity-Theft Behavior via Multi-Source Data

WWW 2020 oral 1 INTRO 1.1 背景 1.1.1 窃电 窃电&#xff08;electricity theft&#xff09;指用户为了逃避电费而进行非法操作的一种行为 常用的反窃电方法可分为两类&#xff1a; 基于硬件驱动的反窃电方法 ​​​​​​​电表开盖检测、集中器检测。。。。 硬件驱动的…

腾讯云3年轻量应用服务器2核2G4M和2核4G5M性能测评

腾讯云优惠之轻量应用服务器3年优惠价格表&#xff0c;目前可以买三年的轻量配置为2核2G4M和2核4G5M&#xff0c;2核2G4M价格三年价格540元&#xff0c;2核4G5M带宽三年756元&#xff0c;当然也可以选择购买一年&#xff0c;第二年续费会比较贵&#xff0c;腾讯云轻量2核2G4M服…

多功能号卡推广分销管理系统 流量卡推广分销网站源码-目前市面上最优雅的号卡系统

一套完善,多功能,的号卡分销系统,多接口,包括运营商接口,无限三级代理,最简单易用的PHP~ 目前市面上最优雅的号卡系统!没有之一 软件架构说明 环境要求php7.3以上(建议低于8.0),MySQL5.6以上,Nginx1.16(无要求) 产品特性 自动安装向导 易于安装使用部署 多个第…

不是小米SU7买不起,而是17.58万的银河E8更有性价比

作者 |Amy 编辑 |德新 疯狂的2023年车市已过。这一年&#xff0c;新势力与传统车企自主品牌在新能源战略上多次交锋。 新能源汽车市场不再由新势力独领风骚&#xff0c;传统车企的新能源品牌进步迅猛&#xff0c;增长势头强劲。 以吉利汽车集团为例&#xff0c;2023年其新能…

1-01初识C语言

一、概述 C语言是贝尔实验室的Ken Thompson&#xff08;肯汤普逊&#xff09;、Dennis Ritchie&#xff08;丹尼斯里奇&#xff09;等人开发的UNIX 操作系统的“副产品”&#xff0c;诞生于1970年代初。 Thompson和Ritchie共同创作完成了Unix操作系统&#xff0c;他们都被称为…

解析数据链路层——组帧

组帧是数据链路层的重要功能之一&#xff0c;它将较长的数据分割成较小的帧以便在网络中传输。在本文中&#xff0c;我们将深入探讨组帧的概念、目的以及常见的组帧技术。 组帧是将数据封装成具有一定格式的帧的过程。帧是数据链路层传输的基本单位&#xff0c;它包含了有效数…

模糊综合评价

第一步&#xff1a;确定评价指标集 确定评语集&#xff1a;如好&#xff0c;很好 第二步&#xff1a;求出模糊评价矩阵P 其中Pij表示方案X在第i个指标处于第j级评语等等隶属度 并且在此阶段需要确认各指标的权系数向量A 第三步&#xff1a;利用矩阵的模糊乘法得到综合评价…

InternLM第2节课作业

基础作业 使用 InternLM-Chat-7B 模型生成 300 字的小故事 熟悉 hugging face 下载功能&#xff0c;使用 huggingface_hub python 包&#xff0c;下载 InternLM-20B 的 config.json 文件到本地

【算法专题】FloodFill 算法

FloodFill 算法 1. 图像渲染 题目链接 -> Leetcode -773.图像渲染 Leetcode -773.图像渲染 题目&#xff1a;有一幅以 m x n 的二维整数数组表示的图画 image &#xff0c;其中 image[i][j] 表示该图画的像素值大小。 你也被给予三个整数 sr, sc 和 newColor 。你应该从…

腾讯云轻量应用服务器可以一次性买三年,2核2G4M和2核4G5M

腾讯云优惠之轻量应用服务器3年优惠价格表&#xff0c;目前可以买三年的轻量配置为2核2G4M和2核4G5M&#xff0c;2核2G4M价格三年价格540元&#xff0c;2核4G5M带宽三年756元&#xff0c;当然也可以选择购买一年&#xff0c;第二年续费会比较贵&#xff0c;腾讯云轻量2核2G4M服…

Unity中Shader面片一直面向摄像机(实现思路)

文章目录 前言一、实现思路1、 我们要实现模型面片一直跟着摄像机旋转&#xff0c;那么就需要用到旋转矩阵2、确定 原坐标系 和 目标坐标系3、确定旋转后坐标系基向量 二、确定旋转后 坐标系基向量 在 原坐标系 下的值1、Z轴基向量2、假设Y轴基向量 和 世界空间下 的Y轴方向一致…