手写数字识别
Python-OpenCV KNN实现手写数字识别
目标:编写一个使用OPenCV的KNN模块实现手写数字识别的程序。
训练数据和测试数据为OpenCV自带的一副包含5000个手写数字的图像digits.
该图像中每个数字有5行,100列(每个手写数字的大小为20x20像素)。
处理过程如下:
- 导入相关模块。
- 读取磁盘文件,图像色彩空间转换。
- 拆分数字,将图像中的每一个数字都拆分为一个独立的20像素x20像素的图像。
- 拆分数据集,将所有数据划分为训练集和测试集。
- 图像重塑,将20x20的图像转换为1x400的列向量,以便于后续处理。
- 为图像“贴上”标签
- 创建knn分类器,完成训练,和识别
- 计算准确率
代码如下:
'''
knn数字识别
'''
import cv2.cv2 as cv
import numpy as np
# ===读取文件色彩空间转换
img = cv.imread('./digits.png')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 色彩空间转换
# ===拆分数字
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)] # 将原始图拆分为单个数字
x = np.array(cells) # 转换为ndarray
print(f'x.shape=\n{x.shape}')
# ===拆分数据集
train = x[:, :50]
test = x[:, 50:]
# ===图片拉伸为1X400的向量
train = train.reshape(-1, 400).astype(np.float32)
test = test.reshape(-1, 400).astype(np.float32)
print(f'train.shape=\n{train.shape}')
# ===贴标签
k = np.arange(10)
train_labels = np.repeat(k, 250)[:, np.newaxis] # 训练集标签
test_labels = np.repeat(k, 250)[:, np.newaxis] # 测试集标签
# ===knn
knn = cv.ml.KNearest_create() # 创建knn分类器对象
knn.train(train, cv.ml.ROW_SAMPLE, train_labels) # 开始训练
ret, result, neighbours, dist = knn.findNearest(test, k=5) # 开始预测
# ===验证
match = result == test_labels
correct = np.count_nonzero(match)
accuracy = correct*100/result.size
print(f'当前使用knn识别手写数字的准确率为:{accuracy}')
运行结果:
x.shape=
(50, 100, 20, 20)
train.shape=
(2500, 400)
当前使用knn识别手写数字的准确率为:91.76