《深度学习中的字符识别在工业视觉中的实际应用》

article/2025/7/16 10:33:12

        最近在公司做了一个构建卷积神经网络来识别字符的项目,编程环境为pycharm2019,使用的是OpenCv+Pytorch进行项目的实现,因此想总结和归纳一下方法。

本次的字符识别项目可以分为以下几个步骤:

一、图像处理和字符分割

二、创建自己的训练集和测试集,为训练集和验证集添加标签

三、重新定义Dataloader函数加载自己的数据集

四、构建卷积神经网络、训练神经网络并测试识别的正确率

五、简单图形界面的实现

一、图像处理和字符分割

        要做字符图像的预处理和准确的字符分割,首先要我们要处理的图像是怎么样的,如图所示就是我这次要识别的工业上的字符图像。

图1-1 识别图像集合

图1-2 字母E
图1-2 字母R

图1-3 字母E

图1-4 字母B

         可以看到我们要去掉的噪声有两种,一种是图片中比较细小的噪声,一种是比较大的黑点,其中最难去掉的是这种比较大的黑点,它一般都是与字符黏在一起,如果处理不好则有可能会消除掉与其黏在一起的字符特征,从而影响识别出正确的字符。在这里我们使用OpenCv模块进行图像预处理,其中内容包括以下几个步骤:

1、图像融合

        这里使用一张与要识别的字符图像大小一样的纯白色图像与字符图像进行融合,目的是让像素点差别更大,以便更容易地识别出字符。说白了就是让黑的地方更黑,让白的地方更白。

图1-5 测试原图

图1-6 图像融合

2、重置图像大小

        使用cv2.resize()函数把图像重置为256x256大小的图像。

3、图像开运算

        使用cv2.morphologyEx()函数对图像再进行开运算,卷积核为7x3大小,目的是去除较小的噪声。

图1-7 图像开运算

4、图像滤波去噪声

        使用cv2.blur()函数和cv2.GaussianBlur()函数(前者为均值滤波,后者为高斯滤波)去除噪声。ps:由于使用开运算以及滤波函数进行去除噪声之后的图像效果只能说是一般般,能够去除小噪声,目前试过最后的方法就是使用图像开运算和均值滤波及高斯滤波来去噪,此前有想过使用边缘检测、膨胀、侵蚀等来去除大黑点噪声,但是由于字符背景的像素变化不大,会影响到所有字符的特征因此只能作罢,采用这一般般的效果,如果后面处理图像的算法有极大的改进会更新。

        本人也有考虑过使用图像的像素值和连通性来处理图像,去除大噪声,如遍历图像中所有的像素点,设置一个像素阈值,使小于阈值的像素点都为255,其余像素值不变,来处理字符图像,经过处理之后有大黑点噪声的图像都能完完整整分割出来,但没有大黑点噪声的图像其中的字符特征就会有一定程度的像素值缺失,导致识别率的下降,因此也只能作罢。

图1-8 均值滤波+高斯滤波

5、图像转化灰度图、图像二值化

        使用cv2.cvtColor()函数把去除噪声后的图像转化为灰度图,之后使用自适应阈值二值化cv2.adaptiveThreshold()函数把图像转为二值图像,即大于阈值的像素值置为255,小于阈值的像素值置为0。

图1-9 灰度图
图1-10 自适应二值化图像

6、查找图像轮廓、绘制轮廓并显示

        使用cv2.findContours()函数查找图像所有的轮廓,使用cv2.drawContours()函数绘制轮廓,并使用cv2.imshow()函数进行显示。

图1-11 绘制轮廓

7、保存轮廓信息到列表,等待识别

        使用cv2.boundingRect函数把各个找到的轮廓坐标、宽和高分别赋值给x、y、w、h,接着根据找到的轮廓的面积和坐标值等条件找到需要的字符图像,并使用cv2.rectangle()函数把字符图像信息保存到前面定义的空列表中,等待训练数据后识别。(x为矩形框的左上角坐标值,y为矩形框的左上角坐标值,w为矩形框的宽度,h为矩形框的高度)

图1-12 保存到列表的图像信息

 至此,图像的预处理和字符分割完成。

二、创建自己的训练集和验证集,为训练集和验证集添加标签

1、创建数据集、重新命名文件夹名称。

        由于此处的项目只用识别26个字母,因此我选用的是车牌识别的英文字母数据集当作自己的数据集,从A字母文件夹到Z文件夹重新以数字0-25命名,并把文件夹名当作训练标签,验证集也是一样的道理。命名完成后如图:

图2-1 重新命名的训练集

 2、制作自己的训练集标签和,验证集标签。

        首先使用os模块遍历训练集中的各个文件夹下的训练图像,把进行训练的图像路径和标签(标签为训练的文件夹名,A为0,...,Z为25),存到label.txt文本里,其中图像路径和标签以“\\”符号隔开,每张图像信息存完进行换行处理。测试集同理,存为test_label.txt文本。存好的训练集和测试集如图:

图2-2 label.txt文件内容

图2-3 test_label.txt内容

 至此,训练集和验证集的标签制作完成。

三、重新定义DataLoader函数加载自己的数据集

         重新定义的DataLoader函数(继承至torch.utils.data.Dataset父类)包括三个需要重新定义的函数(这里参考的是大佬的文章,但具体是谁我忘了,因此就没有给出链接):

1、初始化函数__init__()函数:

        我定义的函数的参数有三个:存有训练图像/测试图像路径和对应标签的txt文件路径filepath,把数值转化为张量的函数transform和target_transform,不过这里只使用了transform函数。

        先根据输入的路径打开txt文件,并通过for循环遍历其中的数据,得到的是图像路径和标签混合在一起的一串数据,接着使用txt.strip()函数去掉其中的换行符,由于之前我们是用符号“\\\\”进行图像路径和标签分割的,因此这里我们使用split()函数把图像路径和对应的标签进行分隔,并以(图像路径,标签)的元组形式存入到空列表imgs里,方便后面的使用。

2、返回图像数据和标签的__getitem()__函数:

        这里的index参数为根据batch_size划分得到的索引,根据索引index可以得到txt文件中的图像路径和标签。

        由于初始化函数中列表imgs存入了图像路径和标签的元组,因此输出imgs的元组需要赋值给fn和label这两个变量,接着使用cv2.imread()函数读出每个路径的信息,并重置训练图像为28x28,设置为灰度图。这里的图像数据和标签数据都需要转化成张量,因此在这添加了一个条件,当transform不为空时,则使用外部定义的转化为张量的函数transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor()])把图像数据和标签数据都转化为张量形式,最后返回图像数据和标签数据。

3、返回图像的训练集/测试集大小的__len()__函数

图3-1 重新定义DataLoader函数

               重新定义DataLoader()函数之后就可以加载我们自己的数据集了,如图所示:

图3-2 加载训练集和测试集

 至此,自己数据集的加载完成。

四、构建卷积神经网络

1、卷积神经网络构成:

 (1)、第一层隐藏层包括卷积层(输入通道为1,输出通道为10,卷积核大小为5x5,步长为1,padding为0,作用是进行图像数据的主要数据特征的提取)、池化层(使用最大池化,kernel_size为2x2,步长为2,目的是进行数据的降维处理)、激活函数(使用ReLU激活函数)。

第二层隐藏层包括卷积层(输入通道为10,输出通道为20,卷积核大小为5x5,步长为1,padding为0,作用是进行图像数据的主要数据特征的提取)、Dropout函数的作用为防止数据的过拟合(在训练集上表现良好,在测试集里表现较差),池化层(使用最大池化,kernel_size为2x2,步长为2,目的是进行数据的降维处理)、激活函数(使用ReLU激活函数)。

  (2)、拉平操作:将多维的输入变成一维的输入。

  (3)、第一层全连接层输入神经元数量为320,输出神经元数量为50;

第二层全连接层输入神经元数量为50,输出神经元数量为26(全连接层的作用是分类器);

  (4)、F.log_softmax()函数:对行进行归一化,返回样本的最大概率。

图4-1 构建卷积神经网络

2、训练函数:

  (1)使用network=CNNMoudle()将网络进行实例化,并使用optim.SGD()函数将优化器设置为随机梯度下降模式。

  (2)首先检测设备是否有GPU,有就使用GPU进行训练,没有就使用CPU进行训练,并使用network.train()函数将网络设置为train模式,接着加载我们自己的训练集,将要训练的图像数据和标签分别赋值给data变量和target变量。

  (3)将SGD优化器进行梯度归零操作,把data变量和target变量转化为GPU需要的张量(此次调用GPU训练因此需要进行转化,不调用就不转化),接着每次传入一个batch的图像并进行前向计算、计算损失、反向传播、优化参数等操作,打印出当前的epoch、当前图像、总训练图像、完成总训练的图像百分比、目前的损失值loss。

  (4)调用torch.save(network.state_dict(), './model.pth')函数将当前训练好的模型保存到当前的文件夹目录下;调用torch.save(optimizer.state_dict(), './optimizer.pth')函数将当前训练好的优化器模型到当前的文件夹目录下。

图4-2 训练函数

3、测试函数:

  (1)使用network=CNNMoudle()将网络进行实例化,首先检测设备是否有GPU,有就使用GPU进行训练,没有就使用CPU进行训练,并使用network.eval()函数将网络设置为eval模式,接着加载我们自己的测试集,将要训练的图像数据和标签分别赋值给data变量和target变量。

  (2)把data变量和target变量转化为GPU需要的张量(此次调用GPU训练因此需要进行转化,不调用就不转化),接着每次传入一个batch的图像并进行前向计算、计算损失,计算出output最大的类别并求出正确分类个数等操作,打印出损失值loss、正确识别的个数/总数、正确率等。

图4-3 测试函数

至此,卷积神经网络构建完成,开始进行训练,训练准确率如下图所示。

图4-4 训练25个epoch的准确率

(ps: 此卷积神经网络的搭建大部分参考的是贵州理工学院计算机视觉霍雨佳老师搭建的手写数字手写体识别的卷积神经网络)

(4)调用模型测试

         首先判断是否调用GPU,接着实例化自己的CNN模型,加载训练好的model.pth模型,将网络设置为eval模式,由于调用GPU需要将图像数据转化成GPU所需张量,因此需要使用torchvision.transforms.Compose()函数转化。

图4-5 调用模型

         接着需要先将要识别的图像进行预处理、字符分割等操作,具体参考第一章。将要识别的图像进行字符分割所得的图像数据存入列表后,遍历列表中的每个图像数据,并进行以下步骤操作:先将图像重置大小为28x28,将图像转化为GPU所需要的张量,在data中的0位置添加一个维度,调用模型传入图像数据data,使用torch.max函数得到最大概率值的索引index,index.item()最后返回标签,为数字0-25。

图4-6 字符预测

        由于最后得到的是标签而不是准确的字符输出,因此需要使用字典进行转换,关键字为标签,变量为标签所对应的字符。最后使用print('识别的图像为:{0}, 识别的结果是{1}'.format(img_label[i][0], label[index]))打印输出识别的图像和识别的结果。

图4-7 识别字符输出

五、简单图形界面的实现

    1、此次项目为了更直观的看到实现的算法效果,于是我用tkinter模块做了一个简单的图形界面,其中的功能包括显示要识别的图形、识别的结果标签、识别字符的正确率标签、选择文件夹识别按钮、选择图片识别按钮、运行识别按钮、退出系统按钮。

图5-1 界面实现代码

    2、选择图片识别函数:

        使用tkinter模块中的filedialog.askopenfilename()函数访问图像路径,initaldir参数为初始的访问路径,返回选择图片的路径,若没有选择图片,则显示文件夹中的一张图片。

图5-2 选择图片函数

    3、选择文件夹识别函数:

        使用tkinter模块中的filedialog.askdirectory()函数访问图像路径,initaldir参数为初始的访问路径,返回选择文件夹的路径,若没有选择图片,则显示文件夹中的一张图片。

图5-3 选择文件夹识别函数

    4、识别运行函数:

        ocr()函数为识别选择图像或选择文件夹所有图像的函数,返回的值分别为图像识别结果集合、识别分割图片的正确率、运行时间。

图5-4 识别运行函数

        5、选择图像识别结果显示:

图5-5 识别结果R

图5-5 识别结果E

图5-6 识别结果E

图5-7 识别结果E

        从识别结果看来,可以知道我们在图像预处理时处理的结果并不是太理想,对于字符有大黑点噪声或者字符之间有连接则不能分割出来。对于其他噪声还是能准确的识别出来,不过此次的项目我的任务是识别出来两个以上字符就行了,因此对于对于我此次的项目来说已经足够了。以后有时间会进行图像预处理的优化。

6、选择图像文件夹识别

        

图5-8 文件夹E

图5-9 文件夹R

至此,整个字符识别项目完成。

六、项目经验总结

        此次用卷积神经网络来实现工业上的字符识别项目需要改善的地方有以下几个:

        1、做识别项目最主要的是图像的预处理,而此次项目的字符图像的预处理明显处理的不够好,对于有较大的黑点噪声去除不够完全,导致在分割字符图像的时候容易分割错误,这里是本次项目最需要优化的地方。

        2、由于此次使用的是车牌识别的英文字符数据集来进行训练,而分割出来的字符图像并不像数据集的字体那么标准,因此在识别某些字符的时候或许会识别错误,如果使用的是由需要识别的字符图像分割而成的字符数据集进行训练,那准确率能提高许多。

        3、在训练时使用的训练集图像数量已经足够,但是验证集的图像数量还是太少了,验证集总数只有80张,如果验证集的再多一点那么训练时的正确率应该会有所下降。

欢迎大家对此项目提出您最宝贵的建议,并在此处留言,与我一同探讨深度学习中的卷积神经网络。


http://chatgpt.dhexx.cn/article/i2veMwFG.shtml

相关文章

python计算机视觉-图像检索和识别

目录 一、原理解析 1.1计算机视觉领域的图像分类是什么意思? 1.2图像分类要如何实现? 1.3Bag-of-features算法和过程? 1)提取图像特征 2)训练字典( visual vocabulary ) 3)图片直方图表示 4)训练分类器 1.4TF-IDF? 1.5当前图像分类中会遇到…

使用计算机视觉和深度学习创建现代 OCR 管道

文章目录 研究和原型设计字深网字检测器组合式端到端系统生产化性能调优优雅 在这篇文章中,我们将带您了解我们如何为[【移动文档扫描仪】构建最先进的光学字符识别(OCR)管道的幕后故事。我们使用了计算机视觉和深度学习的进步,如…

最流行的4个机器学习数据集

最流行的4个机器学习数据集 机器学习算法需要作用于数据,而数据的本质则决定了应用的机器学习算法是否合适,而数据的质量也会决定算法表现的好坏程度。所以会研究数据,会分析数据很重要。本文作为学习研究数据系列博文的开篇,列举…

机器学习——数据集预处理(数据查看和空值处理)

目录 前言 数据集查看 前言 目的:本数据集是为了分析炉丝功率和炉膛温度以及样品盒内部温度之间的关系,分析温场的分布等。 来源:本数据集的来源是实验获得的数据。 特点:特征维度高,数据量大。 数据集查看 1.查…

推荐收藏:50个最佳机器学习公共数据集

外国自媒体mlmemoirs根据github、福布斯、CMU官网等信息,整理了一张50个最佳机器学习公共数据集的榜单,为大家分享一下~ 作者:mlmemoirs 郭一璞 编译 外国自媒体mlmemoirs根据github、福布斯、CMU官网等信息,整理了一张50个最佳…

8种适用于不同机器学习问题的常用数据集

要找到一定特定的数据集可以解决各种机器学习问题,是一件很难的事情。越来越多企业或研究机构将自己的数据集公开,已经成为全球的趋势,这也将有助于大家进行更多研究。 近期,亚马逊高级技术顾问 Will Badr 分享了 8 种适用于不同…

【ML】机器学习数据集:sklearn中回归数据集介绍

目录 1. Boston房价预测数据集2. California房价预测数据集3. 糖尿病预测数据集 在机器学习的教程中,我们会看到很多的demo,这些demo都是基于python中自带的数据集。今天我们将介绍三个用于回归预测的数据集。 1. Boston房价预测数据集 该数据集将在sci…

浅谈机器学习之数据集构建

浅谈机器学习之数据集构建 ​ 正如大家现在知道的,深度学习模型(DL)和机器学习模型(ML)是数据驱动型任务,在近乎完美的数据集面前,模型间的细微差异可以忽略。但要获得覆盖目标场景所有特征的样本,不仅要耗费巨大的人力物力&…

机器学习经典开源数据集盘点

在机器学习任务实施前,如何快速寻找到可用数据集,是令每一位研究人员最头痛的事情。本文为大家列举了八大主流数据集来源,不仅包含大量的数据集信息,而且包含了描述、用法以及一些实施案例等。 01 Kaggle数据集 Kaggle数据集地址h…

免费的机器学习数据集网站(6300+数据集)

今天给大家分享一个免费获取机器学习数据集网站: Machine Learning Datasets | Papers With Code 有想法但没有数据集的同学的福音,网站届满很简洁,及本本上提供的了一般可用的各类数据集,我们可以进行各类影像、评论和点云等数…

学习机器学习算法过程中的常用数据集

文章目录 【数据集1】forge:小型模拟分类问题数据集【数据集2】wave:小型模拟回归问题数据集【数据集3】cancer:中型实际分类问题数据集【数据集4】boston:中型实际回归问题数据集 以下数据集为学习机器学习算法时,经常…

虚拟机系统iso镜像下载_如何下载正版系统镜像

许多网友想装系统,可是不会装(后期会推装系统的文章),而且网上的系统有的装有全家桶,有的又有捆绑软件,严重的还有病毒。那么,在哪里去下载正版,安全的系统镜像呢 "MSDN,我告诉你"这个…

Win7下安装xp虚拟机

在win7下安装Oracle VM VirtualBox虚拟机,然后在安装xp程序。 准备工作: 1. Oracle VM VirtualBox虚拟机 2. 一张xp安装版的镜像盘(这里一定是安装版而不是Ghost版,如果想知道ghost版的会出现什么问题,不妨自己试试。&…

虚拟机系统iso镜像下载_[原版镜像]macOS Mojave 10.14.1 原版 iso 镜像- 虚拟机专用

[原版镜像]macOS Mojave 10.14.1 原版 iso 镜像- 虚拟机专用 Notes: 1. 此镜像仅供用于虚拟机安装, 不能制作启动 u 盘. 2. 此镜像和专栏文章: macOS Mojave 10.14.2 原版镜像 皆可用于虚拟机安装 macOS. 另: 此镜像为苹果官方免费 macOS 镜像和工具制作而成, 没有任何第三方内…

微软官方提供的免费正版 Windows 8.1/Win10/7/XP/Vista 操作系统虚拟机镜像下载

微软官方提供的免费正版 Windows 8.1/Win10/7/XP/Vista 操作系统虚拟机镜像下载 https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ 相信做过网页开发/前端的同学都知道,测试各个浏览器的兼容性是最麻烦的事情之一,单单 IE 就有 N 个版…

基于snap7在vs上通信

这是个已有的snap7通信示例: 首先你得有visual studio,然后 1.在snap7官网上下载文件snap7-full-1.4.2 2.打开snap7-full-1.4.2\examples\dot.net\WinForm\CSharp\CSharp.sln 3.直接编译,它会报错 具体正确的解决方法不太懂,我就…

Snap7 西门子S7系列PLC的通信库 简介

目录 简介参考Snap7 简介Snap7 用途适用系统支持语言西门子S7通信介绍Snap7 组件Sanp7 API源码、手册、样例下载 简介 最近在开发一个项目,作为技术帝,已经完成工艺、机械设计的设计,项目过多,也是为了让自己更加?叉&#xff0c…

通过Snap7与 LOGO!8PLC通信

前言 因一项目需要web控制LOGO! PLC,利用西门子自带的免费LOGO!8.2 Web Editor工具可以很完美的做web页面开发。可以参考视频教程。此外西门子还提供数据导出到excel工具——LOGO8.2 Access Tool。 上面两款工具虽然使用起来非常便捷,但还是想结合Snap…

python使用Snap7读写西门子S7系列PLC

python使用Snap7读写西门子S7系列PLC 1.简介 Snap7 Snap7是一个基于s7通信协议的开源软件包,作者是Davide Nardella,该软件包封装了S7通信的底层协议,可使用普通电脑通过编程与西门子S7系列PLC进行通信 Snap7三大对象组件:客户…

jetson nano上编译与使用西门子PLC通讯库snap7

文章目录 一.西门子snap7介绍二.西门子S7通讯介绍三.jetson nano编译snap7库四.Qt Cmake导入snap7库五.snap7主要函数说明1.与PLC建立连接2.读写PA区变量3.读写MK区变量 六.通讯程序示例 一.西门子snap7介绍 官网:https://snap7.sourceforge.net/ Snap7 是一个基于…