【机器学习】KNN算法实现手写板字迹识别
文章目录
- 【机器学习】KNN算法实现手写板字迹识别
- 1. 前言
- 2. 实验背景
- 3. 测试过程
- 3.1 手写板及测试数据的制作
- 3.2 加载训练数据并进行KNN模型搭建
- 3.3 结果预测
- 4. 总结
【机器学习】KNN算法实现手写板字迹识别
1. 前言
上篇博客通过KNN算法实现鸢尾花数据集分类,在博客最后对KNN算法是否适合于图像分类进行了讨论。本篇博客通过KNN算法实现手写板字迹识别,通过人机交互的模式验证KNN算法是否合适于图像分类。
2. 实验背景
在制作手写体数据集的过程中,常会出现训练数据和测试数据都是出自同一个人的笔迹,此时KNN模型对测试数据友好,但这其实并不符合实际情况。因此本次实验将不同人的笔迹作为训练集,为了增加人机交互性,我们实现了一个简单的手写板进行测试集的制作。
数据集类型 | 数据集来源 | 数据集个数 |
---|---|---|
训练集 | 收集不同人群的手写体,并转换成01矩阵的txt文件格式 | 1974 |
测试集 | 通过python实现手写板,将自己的手写体作为测试集进行预测 | 1 |
3. 测试过程
测试步骤:
1. 设计手写板
2. 制作测试数据
3. 加载训练数据
4. 通过KNN算法进行训练
5. 得到预测结果
3.1 手写板及测试数据的制作
基本思路:通过手写板写入内容,将其保存为图片(512 x 512)。再将图片转换为01矩阵(32 x 32)并保存为txt文件格式作为测试数据。
# 手写板,通过opencv实现
def draw(event,x,y,flags,param):global ix,iyif event==cv2.EVENT_LBUTTONDOWN:drawing=Trueix,iy=x,yelif event==cv2.EVENT_MOUSEMOVE:if drawing==True:cv2.circle(img,(x,y),30,(0,0,0),-1)elif event==cv2.EVENT_LBUTTONUP:drawing=Falseif __name__ == "__main__":# 通过手写板制作图片测试集img=np.zeros((512,512,3),np.uint8)for i in range(512):img[i,:]=255cv2.namedWindow('image')cv2.setMouseCallback('image',draw)while(1):cv2.imshow('image',img)if cv2.waitKey(1) & 0xFF == ord(' '):cv2.imwrite('1.jpg',img)breakcv2.destroyAllWindows()# 将图片转换为0,1矩阵并记录在txt文件中img1 = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)res=cv2.resize(img1,(32,32),interpolation=cv2.INTER_CUBIC)pic=[]for i in range(32):for j in range(32):if res[i][j]<=200:res[i][j]=1else:res[i][j]=0pic.append(int(res[i][j]))filename = 'out.txt'with open(filename, 'w') as name:for i in range(32*32):name.write(str(pic[i]))if (i+1) % 32 == 0:name.write("\n")
3.2 加载训练数据并进行KNN模型搭建
这里的KNN算法与之前鸢尾花分类的算法一样,首先将测试数据按照训练数据维度进行转换,并通过欧式距离进行排序(鸢尾花分类通过计算每条数据之间的距离;字迹识别通过计算每张图片之间的距离),最后选出K个最近的数据并筛选频率最高的标签作为预测结果。
数据加载方式的差别有两个,第一是尺寸信息更丰富,需要将(32,32)维度转为(1,1024)维度方便欧氏距离的计算;第二是标签需要自己设置,这里采用常见的文件名分类法。
# 图像转向量,将(32,32)转为(1,1024),目的在于实现KNN算法的距离计算
def img2vector(filename):vector = np.zeros((1, 1024))file = open(filename)for i in range(32):str = file.readline()for j in range(32):vector[0, 32*i+j] = int(str[j])return vectordef KNN(Test, Train, labels, k):dataSetSize = Train.shape[0]# 求像素的欧氏距离distance = np.tile(Test, (dataSetSize, 1)) - Train sqdistance = distance ** 2sqdistances = sqdistance.sum(axis=1)distances = sqdistances ** 0.5 # 得到训练集的下标sortedDistIndicies = distances.argsort()# 得到K个欧式距离最近的labelresult = []for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]result.append(voteIlabel)print(result)collection = Counter(result)result = collection.most_common(1)return result[0][0]def main():# 载入处理训练集和标签labels = []Train_list = listdir('knn/digits/trainingDigits')batch = len(Train_list)Train = np.zeros((batch, 1024))for i in range(batch):name = Train_list[i] # name得到每个文件名称,"0_0.txt"filename = name.split('.')[0].split('_')[0]labels.append(filename) # filename表示标签列表Train[i, :] = img2vector('knn/digits/trainingDigits/%s' % name)# 这里我设计的是将手写板的图像转换为0,1矩阵并记入txt中作为测试集Test = img2vector("out.txt")result = KNN(Test, Train, labels, 3)print(result)
3.3 结果预测
训练数据:
链接:https://pan.baidu.com/s/1Zh0rYwvovmm4drEOpjLS8A
提取码:mjll
全部代码:
import cv2
import numpy as np
from os import listdir
import operator
from collections import Counterdrawing=False# 图像转向量,将(32,32)转为(1,1024),目的在于实现KNN算法的距离计算
def img2vector(filename):vector = np.zeros((1, 1024))file = open(filename)for i in range(32):str = file.readline()for j in range(32):vector[0, 32*i+j] = int(str[j])return vectordef KNN(Test, Train, labels, k):dataSetSize = Train.shape[0]# 求像素的欧氏距离distance = np.tile(Test, (dataSetSize, 1)) - Train sqdistance = distance ** 2sqdistances = sqdistance.sum(axis=1)distances = sqdistances ** 0.5 # 得到训练集的下标sortedDistIndicies = distances.argsort()# 得到K个欧式距离最近的labelresult = []for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]result.append(voteIlabel)print(result)collection = Counter(result)result = collection.most_common(1)return result[0][0]def main():# 载入处理训练集和标签labels = []Train_list = listdir('knn/digits/trainingDigits')batch = len(Train_list)Train = np.zeros((batch, 1024))for i in range(batch):name = Train_list[i] # name得到每个文件名称,"0_0.txt"filename = name.split('.')[0].split('_')[0]labels.append(filename) # filename表示标签列表Train[i, :] = img2vector('knn/digits/trainingDigits/%s' % name)# 这里我设计的是将手写板的图像转换为0,1矩阵并记入txt中作为测试集Test = img2vector("out.txt")result = KNN(Test, Train, labels, 3)print("预测结果:", result)# 手写板,通过opencv实现
def draw(event,x,y,flags,param):global ix,iy,drawingif event==cv2.EVENT_LBUTTONDOWN:drawing=Trueix,iy=x,yelif event==cv2.EVENT_MOUSEMOVE:if drawing==True:cv2.circle(img,(x,y),30,(0,0,0),-1)elif event==cv2.EVENT_LBUTTONUP:drawing=Falseif __name__ == "__main__":# 通过手写板制作图片测试集img=np.zeros((512,512,3),np.uint8)for i in range(512):img[i,:]=255cv2.namedWindow('image')cv2.setMouseCallback('image',draw)while(1):cv2.imshow('image',img)if cv2.waitKey(1) & 0xFF == ord(' '):cv2.imwrite('1.jpg',img)breakcv2.destroyAllWindows()# 将图片转换为0,1矩阵并记录在txt文件中img1 = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)res=cv2.resize(img1,(32,32),interpolation=cv2.INTER_CUBIC)pic=[]for i in range(32):for j in range(32):if res[i][j]<=200:res[i][j]=1else:res[i][j]=0pic.append(int(res[i][j]))filename = 'out.txt'with open(filename, 'w') as name:for i in range(32*32):name.write(str(pic[i]))if (i+1) % 32 == 0:name.write("\n")# 开始测试main()
4. 总结
大家有兴趣可以直接copy运行看看,预测结果还算可观。但相比深度学习方法精度略显不足。这是因为图片的语义信息是高级信息,无法通过常规的聚类以及距离进行语义判定。我们在做KNN实验时可以尝试输出测试数据与每个训练数据之间的距离,当样本足够时会发现距离相同的样本并不少且标签还不同,这就体现除了KNN算法的一个bug。
总结得出,KNN算法可以在简单的图像数据上进行测试(例如:灰度数据),但在RGB图像甚至更加高维的数据上并不适用。
【机器学习】KNN算法实现手写板字迹识别相关推荐
- 课程设计(毕业设计)—基于机器学习KNN算法手写数字识别系统—计算机专业课程设计(毕业设计)
机器学习KNN算法手写数字识别系统 下载本文手写数字识别系统完整的代码和课设报告的链接(或者可以联系博主koukou(壹壹23七2五六98),获取源码和报告):https://download.csd ...
- Python3:《机器学习笔记与实战》之Knn算法(2)识别手写数字
Python3:<机器学习笔记与实战>之Knn算法(2)识别手写数字 转载请注明作者和出处:https://blog.csdn.net/weixin_41858342/article/de ...
- 机器学习knn算法学习笔记使用sklearn库 ,莺尾花实例
** 机器学习knn算法学习笔记使用sklearn库 ,莺尾花实例. 具体knn算法是怎样的我这里就不再详细论述.在这里我注意总结我使用knn算法进行一个分类的分析 ** 分析过程 1.前期准备 引入 ...
- 基于KNN算法的手写体数字识别
基于KNN算法的手写体数字识别 KNN分类算法是一种经典的分类算法,属于懒惰学习算法的一种. 1.算法原理 工作原理:存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道 ...
- 【Python】基于kNN算法的手写识别系统的实现与分类器测试
基于kNN算法的手写识别系统 1. 数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...
- 机器学习KNN算法实践:预测城市空气质量
出品:Python数据之道 作者:叶庭云 整理:Lemon 机器学习KNN算法实践 预测城市空气质量 「Python数据之道」导读: 之前在公众号上分享过 "图解KNN算法" 的内 ...
- knn算法测试手写识别系统准确率
手写识别系统,KNN算法实现手写识别系统的准确率 (准确率=测试分对的样本数/总的样本数) import numpy as np from itertools import chain from os ...
- 机器学习 —— KNN算法简单入门
机器学习 -- KNN算法简单入门 第1关:手动实现简单kNN算法 1 KNN算法简介 1.1 kNN 算法的算法流程 1.2 kNN 算法的优缺点 1.3 编程要求+参数解释 2. 代码实现 3. ...
- 机器学习——KNN算法
机器学习--KNN算法 文章目录 机器学习--KNN算法 前言 一.KNN原理基础 二.sklearn的基本建模流程 三.KNN算法调优:选取最优的K值 四.KNN中距离的相关讨论 1. KNN使用的 ...
最新文章
- android 52 粘滞广播
- Anaconda环境下OpenCV的安装
- 初学者自学python要看什么书-初学者如何学习Python?掌握这17个实用小技巧快速入门!...
- WF,WPF,Silverlight的DependencyProperty 附加属性
- Android快速阅读依赖的代码,Java Android快速阅读完整文件
- recv 和 send 阻塞和非阻塞的区别
- 浅谈分布式一致性:Raft 与 SOFAJRaft
- Linux 便笺技巧专栏
- win32调用系统颜色对话框
- LeetCode 5364. 按既定顺序创建目标数组
- 指纹支付为什么没有推广?
- android MVC
- 计算机网络 自顶向下方法 第四章 网络层
- ActiveMQ下载安装使用教程
- HG_REPMGR configure配置
- [前端积累]--响应式布局(三)
- 数据科学和机器学习中的优化理论与算法(下)
- 如何让你的Linux程序程序后台运行
- “熊孩子”乱敲键盘就攻破了Linux桌面,大神:17年前我就警告过你们
- 硬件防火墙 与软件防火墙