学习opencv——手写数字识别(1)

OCR(Optical Character Recognition,光学字符识别),如今已经广泛的运用到了各种领域。本次创建一个识别手写数字的程序,使用的是knn算法,属于机器学习中的监督学习,需要大量的训练数据样本进行训练,然后根据训练结果进行识别。 
这里写图片描述 
图中绿色的点会根据k的值取值,再根据取到值颜色的多少来判断绿色的点是属于红色还是蓝色。把这个过程就叫做分类。

OpenCV安装包里有一张图片digits.png(如下图),图片上是5000个手写数字,每个数字重复500遍,分别是0-9。每个数字都是20x20的小图。我们将这个图片在重新排成一行含有400个像素点的新图像。以这个为特征集,所有像素的灰度值。 
digits.png

1.运行环境

操作系统:win7 64位 
python3.5.2 
opencv3.2

2.主要方法

cv2.ml.KNearest_create()

创建一个K-Nearest Neighbour分类器

3.代码

import numpy as np
import cv2

#读取图片转为灰度图
img = cv2.imread('digits.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#把图片分隔成5000个,每个20x20大小
cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]

#再转成numpy数组
x = np.array(cells)

#一半用来训练的数组,一半用来测试的数组
train = x[:,:50].reshape(-1,400).astype(np.float32)
test = x[:,50:100].reshape(-1,400).astype(np.float32)

#创建训练和测试的标签
k = np.arange(10)
train_labels = np.repeat(k,250)[:,np.newaxis]
test_labels = train_labels.copy()

#创建一个K-Nearest Neighbour分类器,训练数据,然后用测试数据测试它
knn = cv2.ml.KNearest_create()
knn.train(train,cv2.ml.ROW_SAMPLE,train_labels)
ret,result,neighbours,dist = knn.findNearest(test,k=5)

#最终检查测试的精确度,比较结果,检查哪些是错误的,最终输出正确率
matches = result == test_labels
correct = np.count_nonzero(matches)
accuracy = correct*100.0 / result.size
print(accuracy)
  • result 

跑一遍程序,最终得到准确率为91.76%。

4.优化

在运行的过程中每次都会去读取图片,准备训练分类器,我们可以运行一次后把它保留下来,下次运行的时候,直接读取这些数据,大大提高运行的效率。

#保存数据
np.savez('data.npz',train=train, train_labels=train_labels)

#下次运行时读取
with np.load('data.npz') as data:
    print data.files
    train = data['train']
    train_labels = data['train_labels']

想要提高手写数字识别率,只有不断的增加训练的样本


猜你喜欢

转载自blog.csdn.net/jgw2008/article/details/79321404