手写数字识别系统之图像分割

背景

本文,主要介绍我以前在学校时候,研究的一些跟手写数字识别相关的技术心得,主要涉及:数字图像处理、特征提取、神经网络等等相关的一些技术。。c++

虽然不少用到的仍是网上现有的比较成熟的算法,可是在这些基础上,我仍是有作了很多算法上的改进的。。算法

而且为了写这个项目,我当时还特意写了一整套神经网络库,从图像处理开始到最后的识别过程,没有使用任何第三方库,都是从0仍是写起 也没有用到opencv啊什么的。编程

上层ui当时用的qt,虽然当时也算是为了跨平台,但那个时候毕竟仍是学生,代码经验欠缺,所以个人基础库对跨平台处理的并非很好。。网络

那个基础库,我稍微简单说下,那是个人第一个开发库,是一个相似boost的c++模板库,里面用到了不少c++的模板元编程的特性,可是如今已经对c++无爱了,因此早已废弃不用了。

不过也就是这个库的开发,很大程度上影响了我以后的编码风格,也是至此以后,我重点转向了对c的开发上。。

这套识别系统,仅仅是我当时为了学习神经网络,拿来练手用的,无法跟那些成熟的相比,识别率不是很高哈,只能给你们用来参考学习了。性能

简介

本文在基本BP算法和数字图像与处理的基础上,经过改进网络、图像处理算法,并结合实践来探索如何实现具备高鲁棒的、高精度的、高效率的脱机数字识别。学习

在这我主要研究脱机单体数字识别,其主要步骤为:优化

overview_1

数字样本的采集

主要采用5行10列的数字样本规格。采集方式是经过扫描样本卡片来获取图像,也尽可能避免样本了的失真,如图:ui

overview_2

图像二值化

主要采用全局阈值分割法和自适应的局部阈值分割法,来实如今不一样亮度背景下的自适应分割,并对结果进行比对。编码

数字提取

目前主要考虑聚类法、矩阵式分割法、连通区域标记法,并比较其优劣,选取效果最好的一种算法。code

图像归一化

主要采用双线性内插和最邻近内插来实现放大,为了减小图像在收缩时带来的失真,目前打算采用求平均法来实现。

特征提取

主要采用逐像素提取法,PCA主成分提取两种方法来实现。

样本学习

主要采用基于BP算法(反向传播学习算法)的神经网络进行识别,并对BP进行必定的改进和优化,来改进训练效果而且适当的提升训练速率。

目前,针对BP的改进算法,主要采添加动量项和自适应步长法。

而对于BP算法,其主要步骤为:

前向计算=〉反向计算=〉权值修正=〉循环迭代

为了进一步改进网络,实现高精度、高效率的识别,打算考虑采用多网络集成法,来进行优化。 主要针对不一样权值、隐层数的基本BP网络进行集成。经过每一个网络分类的结果进行加权输出,来达到有效的分类。

阈值分割

阈值分割法是一种基于区域的图像分割技术,其基本原理是:经过设定不一样的特征阈值,把图像像素点分为若干类。

在本文中,咱们主要处理针对两类的分割,令阈值为T,图像像素对应的灰度级为f(x, y),那么经阈值分割后的图像g(x, y)定义为:

split_1

所以,标记为1的像素对应于对象,也就是前景,而标记为0的对象对应于背景,也就是咱们一般所说的图像二值化。

利用阈值分割进行图像二值化的主要难题就是阈值的选取,事实证实,阈值的选择的恰当与否对分割的效果起着决定性的做用。

经常使用的阈值分割方法有如下三种:

总体阈值法

利用整幅图像的信息对图像求出最优阈值, 在二值化分割过程当中只使用这一个固定阈值,所以计算量小,但对于亮度条件很差的图像的分割效果较差。

局部阈值法

它是把原始图像分为几个小的子图像,再对每一个子图像求出最佳阈值。所以效果较好,但开销较大,且局部大小不太好肯定,过小容易失真,太大效果不显著。

动态阈值法

它的阈值求取方法不只取决于该像素的灰度值及其领域内像素灰度值, 并且还与像素的坐标位置有关, 这种方法灵活性大, 可是复杂度高, 计算量和时间开销都比较大。

而冈萨雷斯写的那本书数字图像处理里面,给出了一种最小偏差阈值,经过利用共轭梯度法对灰度直方图进行双峰的高斯密度曲线进行拟合,求取最佳阈值,效果至关好,可是计算太大,并且对于双峰不显著的图像比较难处理,还需进行附加的单峰检测,并进行插值处理,因为过于复杂且实现也至关困难。

split_2

而本文采用具备自适应性的OTSU局部阈值法来分割图像,并对OTSU和局部阈值法进行了改进,不只提升了性能并且改善了分割效果,对于亮度不均匀的图像也能实现较好的分割。

最大类间方差法(OTSU)

由Otsu于1978年提出的最大类间方差法以其计算简单、稳定有效,一直广为使用。其主要思想就是选取阈值使其类内方差最小化或类间方差最大化。Otsu算法不只计算简单,并且可以应用于多阈值肯定,所以能够说是一种至关好的阈值选取方法。 咱们一般采用最大化类间方差,来实现阈值分割,其类间方差定义为:

otsu_1

其中

|| u || 图像中总的灰度均值 || || u1 || 图像中小于阈值T的像素灰度均值 || || u2 || 图像中大于阈值T的像素灰度均值 || || n1 || 图像中小于阈值T的像素数 || || n2 || 图像中大于阈值T的像素数 ||

所以,只需经过遍历256个灰度级,寻找使其类间方差最大的那个灰度值就是最佳阈值T。

OTSU的实现与改进

然而若是每次遍历都须要从新计算阈值两边的均值与像素数的话计算量是至关大的,若是可以在下次遍历时利用上次计算的结果,那么计算量能够大大减小。 假设灰度直方图为,图像总均值为,图像总像素数为,那么其递推方式以下:

otsu_2

为了进一步简化计算,咱们能够经过用otsu_3来替换,获得

otsu_4

因为n在递归中不变能够省略,所以能够改成

otsu_5

因为本文是针对字符图像的分割,因为字符的笔画一般较细,一般只占图像的1/4都不到,所以能够适当的调整阈值,以实现较好的分割效果,改进后的阈值为

otsu_6

局部阈值的实现与改进

然而在实际图像中, 因为噪声或其余干扰等因素的影响,OTSU阈值分割并不能使图像分割获得满意的结果, 每每会产生严重的分割错误。这是由于图像的灰度直方图分布不必定 出现明显的峰和谷, 像素灰度值仅仅反映了像素灰度级的幅值大小, 并无反映出像素与邻域的空间相关信息。

经过具体的实验发现:

当图像亮度分布不均匀时,每每没法获得好的分割效果,一般会出现大块的黑块,或者过渡分割而丢失信息的状况。

所以,能够经过对图像进行分块,针对每一小块进行OTSU分割,能够减小这些状况的发生,可是这又会出现不但愿的“棋盘”效果,为了不这种状况的发生,能够采用以下改进的局部阈值算法:

遍历图像中每一像素,在该像素的邻域内进行灰度统计,计算OTSU阈值,并仅对该点进行阈值分割。

这样就能在较好的分割效果下实现像素平滑过渡,避免了“棋盘”效应,因为在当像素移动时,只有一行或一列改变,因此能够在每步移动中,以新数据更新前一个位置获得的直方图,从而避免了每次从新计算整个直方图,大大减小了计算量,使其在一个可接受的范围内。

为了防止部分区域受到噪声干扰而产生的黑块现象,能够在进行局部阈值处理前,进行三阶的平滑处理,效果至关显著。

结果

原图

split_3

经全局阈值处理后的图象

split_4

经改进的局部阈值处理后的图像

split_5

总结

由上图可见,经改进的局部阈值处理后的图像的效果仍是至关明显的,但是仍是有些不足之处。。

就是处理后的图像笔画较粗,容易填掉数字中的空洞,尤为是4,6,8,9这些含有小孔的数字,这些都有待进一步改进。

后续,我还会总结下:倾斜矫正、数字提取、特征提取、神经网络相关的一些心得和改进算法。。

最后,再贴两张hnr项目,界面截图哈。。

before after


TBOOX项目主页

相关文章
相关标签/搜索