利用SVM(支持向量机)和MNIST库在OpenCV环境下实现手写数字0~9的识别

来源:互联网 发布:南昌seo自动优化软件 编辑:程序博客网 时间:2024/04/28 07:42

SVM是一种有机监督的机器学习方式,什么叫有监督?就是机器在学习时,有先验知识~SVM的理论细节很复杂,因为现在还不需要,所以博主也没有去深入研究,以后需要的时候再去学习吧。简单地说,SVM就是把一幅图进行各种运算,提取出一幅图像的特征,特征用向量表示,通过不断的学习,让这个向量越来越逼近图像的真实特征,具体的手段是把图像数据不断往高维抽像。

OpenCV3.0.0中提供了类SVM用于实现SVM支持向量机算法,实际上这个类调用的是台湾林智仁等开发设计的LIBSVM来实现SVM训练的,详细的使用方法可参见网页http://blog.sina.com.cn/s/blog_4c70701801013xui.html 

既然是调用别人写好的算法,那程序就简单了,接下来,就是要给SVM喂食(提供训练库),MNIST库是美国人提供的一个免费的手定数字识别库,我前边已经写了博文给了下载地址:手写数字图片库MNIST百度网盘下载链接~ 这个库由四部分组成,下面分别介绍:

train-images-idx3-ubyte:训练图像源

train-labels-idx1-ubyte:训练图像的标签-就是"train-images-idx3-ubyte"中每幅图像中写的是什么数字

t10k-images-idx3-ubyte:测试图像

t10k-labels-idx1-ubyte:测试图像的标签-就是"t10k-images-idx3-ubyte"中每幅图像中写的是什么数字

下面是使用上面的训练图像和测试图像进行SVM训练并进行性能测试的代码

PS: 代码比较简单,注释也写得很清楚,这里就不作解释了!‘

代码中用到的训练库我上面已经提供了下载链接!

//OpenCV版本3.0.0  //交流QQ2487872782 代码编号:2016-8-001抱歉,此代码目前暂不能公开,如需代码,请联系QQ2487872782购买!本篇博文中的几个代码打包售价30元人民币!

运行结果如下图所示

从运行结果中我们可以看出,六万张训练生成SVM的XML文件用了564秒,随后用训练的结果进行训练数据的测试,一万张测试图片正确的识别个数为9833,错误率为1.67%。

接下来,我们修改程序,使其识别测试库t10k-images-idx3-ubyte的单张图像,手写数字图片库MNIST百度网盘下载链接~有一个压缩包,里边已经把测试图像全面输出为一张一张的bmp图像,我们用其中一张图像进行测试,以便进一步测试我们自己手写的图像。这段代码的关键是要将单幅图像的格式转化为类SVM中predict能处理的数据格式。代码如下

代码中用到的XML文件和两幅图像下载链接:http://pan.baidu.com/s/1bpwqN8b

//OpenCV版本3.0.0  //交流QQ2487872782 代码编号:2016-8-002抱歉,此代码目前暂不能公开,如需代码,请联系QQ2487872782购买!本篇博文中的几个代码打包售价30元人民币!

运行结果如下所示

  

可见,能正确识别单幅测试图像!

接下来,再修改程序,使其能识别自己手写的单个数字(既然是单个,则无分割问题):

程序中用到的手写数字图像下载链接:http://pan.baidu.com/s/1o7JuKGE

特别说明一下:程序中,提取数字所在区域的立式外接矩形我通过手工确定在boundRect[的第9个,实际上每幅图像是不一样的,甚至更一般的情况下需要写专门的程序作处理,在实际应用时,必须要修改这一部分程序,否则根本没有通用性,提供一下我现在想到的思路吧:把boundRect[中最左上的坐标和最右下的坐标找出来,这两个点构成的矩形就是数字的外接矩形了!

//OpenCV版本3.0.0    代码编号:2016-8-003抱歉,此代码目前暂不能公开,如需代码,请联系QQ2487872782购买!本篇博文中的几个代码打包售价30元人民币! 

运行结果如下图所示


输出的28*28图像下载链接:http://pan.baidu.com/s/1slTEowP

用上面的程序输出的图像导入到上面给的识别单幅图像的程序中,结果如下


可见,自己手写的数字通过一系列图像预处理操作后可以被正确识别!


0 0