在另一篇学习笔记里,记录了通过k-近邻算法识现的手写数字识别。​

本文使用SVM算法。SVM在文本分类、手写文字识别、图像分类、生物序列分析等实际应用中表现出了非常好的性能。

算法

  1. 为每个数字各准备4个样本图像
  2. 将图像调整为8*8尺寸,读取样本图像
  3. 读取未知样本图像,将未知图像调整为8*8尺寸,提取图像特征码,生成图像特征组
  4. 将未知样本图像特征组送入SVM仿真测试,仿真输出值为根据图像识别出的数字。

数据集

USPS美国邮政服务手写数字识别库

​http://www.datatang.com/data/11927​

用于数字的手写识别。库中共有9298个手写数字图像(均为16*16像素的灰度图像的值,灰度值已被归一化),其中7291个用于训练,2007个用于测试。

手写数字MNIST数据集

​http://www.datatang.com/data/3082​

用于数字的手写识别。库中共有6万个训练集和1万个测试集。
​​​ http://yann.lecun.com/exdb/mnist/​

用于笔交互的手写数字识别(UCI)

​http://www.datatang.com/data/578​

用于数字的手写识别。库中共有44个人的250个手写数据例子

用于处理和理解手写阿拉伯语的数据集

​http://www.datatang.com/data/2188​

用于阿拉伯语的手写识别。包括51个人的2万个手写数据。

实现

#-*- coding: utf-8 -*-

import numpy as np
import mlpy
import cv2
print("load...")

def getnumc(fn):
'''返回数字特征'''
fnimg = cv2.imread(fn)
img = cv2.resize(fnimg,(8,8))
alltz=[]
for now_h in range(0,8):
xtz=[]
for now_w in range(0,8):
b=img[now_h,now_w,0]
g=img[now_h,now_w,1]
r=img[now_h,now_w,2]
btz = 255-b
gtz = 255-g
rtz = 255-r
if btz >0 or gtz>0 or rtz>0:
nowtz=1
else:
nowtz=0
xtz.append(nowtz)
alltz+=xtz
return alltz

#读取样本数字
x=[]
y=[]
for numi in range(1,10):
for numij in range(1,5):
fn='nums/'+str(numi)+'-'+str(numij)+'.png'
x.append(getnumc(fn))
y.append(numi)

x=np.array(x)
y=np.array(y)
svm = mlpy.LibSvm() #svm_type='c_svc', kernel_type='poly', gamma=10)
svm.learn(x,y)

print (svm.pred(x))

for iii in range(1,10):
testfn='nums/test/'+str(iii)+'-test.png'
testx=[]
testx.append(getnumc(testfn))
print(svm.pred(testx))

代码在windows下运行未通过,mlpy.LibSvm可能存在兼容问题。CentOS调试后贴出运行结果。