01数码识别

这学期的人工神经网络课程已经进行完了第三章内容,关于经典网络重要的BP(误差反向传播网络)是所有学习人工神经网络最先接触到的一个实用网络。它的原理相对比较简单,在很多平台中都非常容易实现。

学习神经网络的基本原理之后,更重要的是能够通过一些应用场合来应用它,使他能够帮助自己解决一些实际的工程问题。

近期购买到的 LC100-A 电感电容测量模块,用于测量一些实验中实验对象的电感、电容值随着其他一些物理变量(工作电压、距离、温度等)所产生变化规律。为了便于实验,需要能够将LC100-A测量数值自动记录。

▲ 上电过程

▲ LC100-A显示的数字

在开始的方式就是直接使用摄像头获取液晶显示数据,然后使用字符识别软件来完成其中数字的识别。

测试一下CNOCR识别效果。它对于屏幕截图中的文字识别效果还不错:

▲ 屏幕截取的一段文字

  • 识别时间:1.98。* 识别结果:

[[‘●’, ‘更’, ‘新’, ‘了’, ‘训’, ‘练’, ‘代’, ‘码’, ‘,’, ‘使’, ‘用’, ‘m’, ‘x’, ‘n’, ‘e’, ‘t’, ‘的’, ‘r’, ‘e’, ‘c’, ‘o’, ‘r’, ‘d’, ‘i’, ‘o’, ‘首’, ‘先’, ‘把’, ‘数’, ‘据’, ‘转’, ‘换’, ‘成’, ‘二’, ‘进’, ‘制’, ‘格’, ‘式’, ‘,’, ‘提’, ‘升’, ‘后’, ‘续’, ‘的’], [‘训’, ‘练’, ‘效’, ‘率’, ‘。’, ‘训’, ‘练’, ‘时’, ‘支’, ‘持’, ‘对’, ‘图’, ‘片’, ‘做’, ‘实’, ‘时’, ‘数’, ‘据’, ‘增’, ‘强’, ‘。’, ‘也’, ‘加’, ‘入’, ‘了’, ‘更’, ‘多’, ‘可’, ‘传’, ‘入’, ‘的’, ‘参’, ‘数’, ‘。’], [‘●’, ‘允’, ‘许’, ‘训’, ‘练’, ‘集’, ‘中’, ‘的’, ‘文’, ‘字’, ‘数’, ‘量’, ‘不’, ‘同’, ‘,’, ‘目’, ‘前’, ‘是’, ‘中’, ‘文’, ‘1’, ‘0’, ‘个’, ‘字’, ‘,’, ‘英’, ‘文’, ‘2’, ‘0’, ‘个’, ‘字’, ‘母’, ‘。’], [’。’, ‘提’, ‘供’, ‘了’, ‘更’, ‘多’, ‘的’, ‘模’, ‘型’, ‘选’, ‘择’, ‘,’, ‘允’, ‘许’, ‘大’, ‘家’, ‘按’, ‘需’, ‘训’, ‘练’, ‘多’, ‘种’, ‘不’, ‘同’, ‘大’, ‘小’, ‘的’, ‘识’, ‘别’, ‘模’, ‘型’, ‘。’], [‘●’, ’ ', ‘内’, ‘置’, ‘了’, ‘各’, ‘种’, ‘训’, ‘练’, ‘好’, ‘的’, ‘模’, ‘型’, ‘,’, ‘最’, ‘小’, ‘的’, ‘模’, ‘型’, ‘只’, ‘有’, ‘之’, ‘前’, ‘模’, ‘型’, ‘的’, ‘1’, ‘/’, ‘5’, ‘大’, ‘小’, ‘。’, ‘所’, ‘有’, ‘模’, ‘型’, ‘都’, ‘可’, ‘免’, ‘费’], [‘使’, ‘用’, ‘。’]]

那么对于前面液晶屏幕识别效果呢:

▲ 只是数字部分

识别结果:
[[’.’, ‘。’, ‘与’, ‘F’, ‘早’, ‘H’]]

好像驴唇不对马嘴。

这主要原因还是原来网络没有针对上述液晶实现数字进行训练过。由于液晶显示图片质量非常好,实际上只需要最简单的BP网络就可以达到很好的效果。

下面给出在MATLAB中构建网络并进行实验的过程。

02准备数据集

使用神经网络解决问题,一个重要的环节就是进行训练数据的准备。通过对采集到的一些图片中的数字进行提取并手工标注,来完成对网络的训练。

1.数字分割

下面是桌面摄像头捕捉到的测量图片,通过简单的图片灰度投影,比较方便将显示数字所在图片中的位置定出。为了简单起见,也可以固定摄像头与LCD相对位置,这样手工定标出结果字符位置也可以适用于后面测量结果。

▲ 液晶数字显示以及数字部分

这个问题简单之处在于所有字符都是等宽,而且对比度非常好,简单的分离就可以将所有的字符单独分离出来。由于摄像头位置固定,所以简单分割之后的字符之后少量的上下左右平移,没有旋转。对于图片位置、尺寸就不再进行归一化。这些差异最后有神经网络来弥补。

▲ 分割出的数字

液晶显示字符的图片对比度很好。但就是有一个问题,在摄像头拍摄的时候,经常会遇到字符变化过程,这就会使得图片中字符呈现两个字符叠加的情况。下面是一些示例:

▲ 数字变化过程的图片

这些过程,说实在的,即使人工识别也会无法分辨。

后面通过人工输入标注了2000多个样本。

2.图片二值化

对于分割的图片进行二值化,可以消除环境光对于图片亮度的影响。在一定程度上,也可以消除液晶字符在变化时所引起的模糊。

▲ 图像二值化对应的点阵

▲ 二值化对应的数组

▲ 二值化对应的数字

上面所有的字符的尺寸是23乘以38点阵。

03训练神经网络

1.构建网络和训练

简单的实验,就用简单的方法。对于前面所得到的字符,不再人工定义它们的特征。仅仅将原来的彩色图片变换成灰度图像,然后排列成23×38=874维向量。然后增加一层中间隐层便组成了最简单的分类网络。

net = patternnet(11)

▲ 构造一个单隐层神经网络

将前面人工标注的样本一半用于训练,全部样本用于测试。下面给出了测试的结果。

plotconfusion(xx, net(yy))

▲ 训练结果

2.训练结果与分析

整体的错误率大约为:ERR= 2.99%。

下面是识别正确的字符。

▲ 识别正确的字符

下面给出了部分识别错误字符的情况。基本上都是一些拍摄到液晶字符在变化过程中的重叠字符情况。这些情况本身在人工标注的时候就存在模糊。

▲ 错误样本集合

▲ 错误的识别字符

3.网络结构与错误率

下面给出了网络的隐层节点个数与识别错误样本个数之间的关系。可以看到当中间隐层节点大于5之后,识别性能就不再有明显的变化了。

隐层节点个数 2 3 4 5 6 7 8 9 10 11
错误数量 1810 656 216 77 69 66 65 72 58 68

▲ 隐层节点个数与错误率

04讨论

使用神经网络解决问题,不是寻找最强大的网络,而是需要最合适的网络。

通过上面的测试结果来看,简单的单隐层网络便可以很好的满足液晶显示数字识别。那么对于那些由于数字跳动所引起的错误该怎么处理呢?

这个问题如果仅仅依靠增加训练样本和改进网络结构是很难进行彻底解决,规避这个错误可以通过对连续识别结果进行比对来解决。对显示数字进行连续快速采集5帧图像,其中液晶跳动往往只发生在其中一帧,或者两帧。那么对于五个图像识别出的数字进行对比,找到相同次数最多的数字作为输出结果。

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY                     -- by Dr. ZhuoQing 2020-10-16
#
# Note:
#============================================================from headm import *
import imgsubpicdir = tsptext2string('pic2dir')
files = os.listdir(picdir)#------------------------------------------------------------
for f in files:fn = os.path.join(picdir, f)if os.path.isfile(fn):printf(f)imgsub.cropimage(fn, imgsub.digitdir)#    breakprintf('\a')#------------------------------------------------------------
#        END OF FILE : TEST1.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# IMGSUB.PY                    -- by Dr. ZhuoQing 2020-10-16
#
# Note:
#============================================================from head import *
from PIL                    import Image#------------------------------------------------------------
'''imageid = 121
boxid = 122imagebox = tspgetrange(imageid)
boxbox = tspgetrange(boxid)printff(imagebox, boxbox)pos_left = boxbox[0] - imagebox[0]
pos_top  = boxbox[1] - imagebox[1]boxwidth = boxbox[2] - boxbox[0]
boxheight = boxbox[3] - boxbox[1]tspsave('digitbox', left=pos_left, top=pos_top, width=boxwidth, height=boxheight)
printff(pos_left, pos_top, boxwidth, boxheight)
'''
#------------------------------------------------------------
left, top, width, height = tspload('digitbox', 'left', 'top', 'width', 'height')
numnum = 7                      # digit numdef cropimage(imagefile, savedir):im = Image.open(imagefile)for i in range(5):cleft = int(left + i * width/numnum)cwidth = int(width/numnum)im1 = im.crop((cleft, int(top), cleft+cwidth, int(top+height)))fbn = os.path.basename(imagefile).split('.')savefn = os.path.join(savedir, fbn[0]+'_%d'%i+'.'+fbn[1])im1.save(savefn)printf(savefn)#============================================================
imname = r'd:\temp\201013173456\0000.bmp'
digitdir = r'd:\temp\digitdir'
if __name__ == "__main__":cropimage(imname, digitdir)#------------------------------------------------------------
#        END OF FILE : IMGSUB.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST2.PY                     -- by Dr. ZhuoQing 2020-10-16
#
# Note:
#============================================================from headm import *
from PIL                    import Imagedigitid = 147
filename = tspgetdopfile(digitid)
printf(filename)im = Image.open(filename)
imdata = im.getdata()
imsize = size(imdata)
imdata = resize(array(im.getdata()).mean(axis=1), imsize[::-1])imb = imdata>80
imb1 = [[int(a) for a in b] for b in imb]
for l in imb1:printf(l)exit()printf(shape(imdata))
printf(imdata[5])#------------------------------------------------------------
#        END OF FILE : TEST2.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# MKDIRALL.PY                  -- by Dr. ZhuoQing 2020-10-16
#
# Note:
#============================================================from head import *
from shutil                 import copyfilelabeldir = r'D:\Temp\digitlabel'
dirstr = r'D:\Temp\digitall'
labelalldir = r'd:\temp\labelall'#------------------------------------------------------------for i in range(11):dirname = os.path.join(dirstr, 'digit_%x'%i)printf(dirname)for f in os.listdir(dirname):fb = os.path.basename(f)fromfile = os.path.join(dirname, f)tofile = os.path.join(labelalldir, fb)copyfile(fromfile, tofile)printf('\a')#------------------------------------------------------------
'''
fileall = os.listdir(labeldir)for f in fileall:fn = os.path.basename(f).split('_')[1]if fn[0] == '.': continuecopydir = os.path.join(dirstr, 'digit_%s'%fn[0])savefile = os.path.join(copydir, os.path.basename(f))printf(fn)copyfile(os.path.join(labeldir, f), savefile)#    breakprintf(len(fileall))
'''
#------------------------------------------------------------
'''for i in range(11):dirname = 'digit_%x'%idirname = os.path.join(dirstr, dirname)printf(dirname)if not os.path.isdir(dirname):os.mkdir(dirname)
'''
#------------------------------------------------------------#------------------------------------------------------------
#        END OF FILE : MKDIRALL.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST4.PY                     -- by Dr. ZhuoQing 2020-10-16
#
# Note:
#============================================================from head import *
from PIL                    import Imagetfname = r'd:\temp\t.txt'
xfname = r'd:\temp\x.txt'filedir = r'D:\Temp\labelall'allfile = os.listdir(filedir)tf = open(tfname, 'w')
xf = open(xfname, 'w')xdata = []
tdata = []#------------------------------------------------------------
for f in allfile:fn = os.path.join(filedir, f)im = mean(array(Image.open(fn).getdata()), axis=1)imint = [int(a) for a in im]xdata.append(imint)imintstr = str(imint).strip('[]')
#    printf(imintstr)fb = f.split('_')[1][0]if fb == 'a': t = 10else: t = int(fb)tdim = [0] * 11tdim[t] = 1tdata.append(tdim)tstr = str(tdim).strip('[]')
#    printf(tstr)tf.write('%s\n'%tstr)xf.write('%s\n'%imintstr)#    imsize = size(im)
#    printf(imsize)
#    imdata = resize(mean(array(im), axis=1), imsize[::-1])#    printf(shape(imdata))#    imint = [[int(a>80) for a in b] for b in imdata]#    for l in imint:
#        printf(l)#    breaktf.close()
xf.close()printf('\a')tspsave('digitdata',x=xdata, t=tdata)#------------------------------------------------------------
#        END OF FILE : TEST4.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTERR.PY                   -- by Dr. ZhuoQing 2020-10-16
#
# Note:
#============================================================from headm import *
from tsmodule.tsdraw        import *x, t = tspload('digitdata', 'x', 't')
#y = tspload('ydata', 'y')result = clipboard.paste().strip('[]').split(';')tdim = []
for r in result:tdim.append(r.split(' '))y = [[int(float(b) > 0.5) for b in a] for a in zip(*tdim)]printf(y[0])err = 0
#------------------------------------------------------------
def t2num(t):if any(t) == 1:return list(t).index(1)else: return 0#------------------------------------------------------------
pltgif = PlotGIF()
for yy,tt,xx in zip(t, y, x):#    if list(yy==tt).count(False) == 0:
#        err += 1
#        plt.clf()
#        plt.imshow(resize(xx, (32, 23)), cmap='gray')
#        plt.title('识别结果:%d'%t2num(yy))
#        plt.draw()
#        plt.pause(.1)
#        pltgif.append(plt)#        if err > 250: breakif list(yy==tt).count(False) > 0:err += 1#        plt.clf()
#        plt.imshow(resize(xx,(38,23)), cmap='gray')
#        plt.title('%s-->%s'%(t2num(yy),t2num(tt)))
#        plt.draw()
#        plt.pause(.1)#        pltgif.append(plt)#printf(list((t[0] == y[0])).count(False))
printf(err)#pltgif.save(r'd:\temp\1.gif')#------------------------------------------------------------
#        END OF FILE : TESTERR.PY
#============================================================

简单BP网络识别数码表字符相关推荐

  1. bp 字母识别 java_Matlab实现BP网络识别字母

    训练样本空间 每个样本使用5×5的二值矩阵表征一个字母.一共10个字母类型,分别是N,I,L,H,T,C,E,F,Z,V.每个字母9个样本.共90个. N1=[1,0,0,0,1; 1,0,0,0,1 ...

  2. java opencv bp网_基于Opencv自带BP网络的车标简易识别

    记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 1.准备工作 1.1 训练集和测试集准备 先将数据集手动划分成训练集和测试集,并分好类,比如第一类就放在文件夹名为0的文件夹下, ...

  3. 基于Opencv自带BP网络的车标简易识别

    代码地址如下: http://www.demodashi.com/demo/12966.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 1.准备工作 1.1 训练集和 ...

  4. opencv 车牌字符分割 ANN网络识别字符

    opencv 车牌字符分割 ANN网络识别字符   原文参考:https://www.cnblogs.com/chenzhefan/p/7629441.html 最近在复习OPENCV的知识,学习ca ...

  5. 基于BP 网络分类器的交通标志识别

    基于BP 网络分类器的交通标志识别 摘要:针对中国全部 3 大类 116 个交通标志,即禁令标志.指示标志.警告标志,用 BP 网络实现分类功能. 实验中使用了 3 种测试集,即加高斯噪声.水平扭曲和 ...

  6. 基于Python的BP网络实现手写数字识别

    资源下载地址:https://download.csdn.net/download/sheziqiong/86790047 资源下载地址:https://download.csdn.net/downl ...

  7. 反向传播网络(BP 网络)

    反向传播网络(BP 网络) 1 .概述 前面介绍了神经网络的结构和模型, 在实际应用中, 我们用的最广泛的是反向传播网络 (BP网络) .下面就介绍一下BP网络的结构和应用. BP网络是采用Widro ...

  8. 简单局域网网络故障排查和处置

    简单局域网网络故障排查和处置 一.了解基本网络构成 1. IP传输通信图 2.有线网络 (一)物理层面 (1)网线 (2)网线的制作 (3)网卡接口 (4)光纤 (5)光纤接口 (6)收发器 (7)集 ...

  9. bp网络和卷积神经网络,bp神经网络

    与传统bp神经网络相比,极限学习机有哪些优点 极限学习机(ELM)算法,随机产生输入层与隐含层间的连接权值及隐含层神经元的阈值,且在训练过程中无需调整,只需设置隐含层神经元的个数,便可获得唯一的最优解 ...

最新文章

  1. php常量 变量,php语言的变量和常量
  2. spring入门-设值方法的差异
  3. dll侧加载_WORD打开时出现加载DLL错误解决方法
  4. CSS中flex和inline-flex的区别
  5. zabbix官方文档磁盘统计
  6. Django权限管理测试
  7. 网站加速--Cache为王篇
  8. zabbix server is not running解决办法
  9. Xshell和Xftp免费版
  10. 学计算机用苹果本,新手小白用苹果电脑搞科研,学会这些才不至于尴尬!
  11. postman使用手册
  12. 有趣好玩的python编程网站
  13. python处理doc格式文档
  14. elasticsearch通用工具类
  15. nginx locating匹配问题(1) ---cookie
  16. 通过SE14重建数据库表
  17. UE4 蓝图设置怪物自动寻路
  18. 基于echarts实现根据鼠标移动轨迹更改曲线值或创建曲线
  19. 睿备份支持linux,【睿备份怎么用】睿备份好不好_使用技巧-ZOL软件百科
  20. 千万别错过!C/C++实现经典围棋大战,秒杀挫败柯洁的AlphaGo

热门文章

  1. Mybatis操作主体流程
  2. 2208: [Jsoi2010]连通数
  3. linux内存操作----kernel 3.5.X copy_from_user()和copy_to_user()
  4. Python标准库_ sys,random,time
  5. Objective-C @property和@synthesize
  6. [转载] 七龙珠第一部——第032话 飞天要塞
  7. Cisco路由器的Flash和NVRAM
  8. 有趣而又被忽略的Unity技巧
  9. effective c++
  10. Android零基础入门第25节:最简单最常用的LinearLayout线性布局