首页 > 其他分享 >KNN图像识别实例--手写数字识别

KNN图像识别实例--手写数字识别

时间:2024-08-16 22:51:27浏览次数:16  
标签:KNN 图像识别 -- cv2 train 图像 np 20

目录

前言

一、导入库

二、导入图像并处理

1.导入图像

2.提取出图像中的数字

3.将列表转换成数组

4.获取特征数据集

5.获取标签数据

三、使用KNN模型

1.创建KNN模型并训练

2.KNN模型出厂前测试

3.使用测试集对KNN模型进行测试

四、传入单个图像,使用该模型进行识别

1.导入图像

2.处理成灰度图

3.获取数据并转换成数组

4.将数据变成KNN模型可使用的维度

5.进行图像识别

总结


前言


本次图像识别所用的图片

点击链接下载保存图片即可使用

这是图像:

一、导入库

  • python图像识别需要用cv2库
import numpy as np
import cv2

二、导入图像并处理

1.导入图像

# 导入图像
img = cv2.imread('figure_0_9.png')
# 将图像处理成灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

2.提取出图像中的数字

  • 在画图工具或者pycharm里可以看见这个图像是2000*1000像素的
  • 每个数字大小都是20*20
# 提取出图像里的数字 这里是等分的
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]  # vsplit 垂直切分; hsplit 水平切分

3.将列表转换成数组

# 将列表转换成数组
x = np.array(cells)
print(x.shape)  # 打印x的各维度大小  (50, 100, 20, 20)

4.获取特征数据集

  • 分离出训练集train 和测试集test
  • 这里使用图片左一半数据做训练,右一半数据做测试
# 分出训练集train 和测试集test
train = x[:, :50]
test = x[:, 50:100]
print(train.shape)       # (50, 50, 20, 20)

# 更改各数据集的维度 变成一个数字一行数据
train_new = train.reshape(-1, 400).astype(np.float32)  # 将第二个维度大小设置成400,第一个维度根据原数据维度自动进行判断
test_new = test.reshape(-1, 400).astype(np.float32)  # 将数组的数据类型转换为 np.float32
print(train_new.shape)    # (2500, 400)

5.获取标签数据集

  • 这里标签数据集自己做出来
# 给各数据集分配标签
k = range(10)
labels = np.repeat(k, 250)  # 将每一个数字重复250次 变成2500行
train_labels = labels[:, np.newaxis]  # 给labels增加一个维度
test_labels = np.repeat(k, 250)[:, np.newaxis]  # 省略写法

三、使用KNN模型

1.创建KNN模型并训练

  • 这里是使用cv2创建KNN模型
# 创建模型并进行训练
knn = cv2.ml.KNearest_create()  # 使用cv2 创建knn模型
knn.train(train_new, cv2.ml.ROW_SAMPLE, train_labels)  # 传入训练集特征数据和标签进行训练
# cv2.ml.ROW_SAMPLE 指示数据是按行排列的 OpenCV 的机器学习模块中的 ROW_SAMPLE 常量用于指明每一行表示一个训练样本

2.KNN模型出厂前测试

# 获取使用KNN识别手写数字模型出厂前测试准确率
ret, result, neighbours, dist = knn.findNearest(train_new, k=3)  # 先使用训练集数据进行出厂前测试
# print(result)
matcher = result == train_labels  # 取出判断之后的布尔值
correct = np.count_nonzero(matcher)  # 统计判断正确的数量
accuracy = correct * 100.0 / result.size  # 计算准确率
print("使用KNN识别手写数字模型出厂前测试准确率为:", accuracy)
# 使用KNN识别手写数字模型出厂前测试准确率为: 96.92

3.使用测试集对KNN模型进行测试

  • 与上面代码差别在,knn.findNearest中的数据集参数和matcher里使用的result以及标签集参数
# 获取当前使用KNN识别手写数字的准确率
ret, result, neighbours, dist = knn.findNearest(test_new, k=3)
matcher = result == test_labels  # 取出判断之后的布尔值
correct = np.count_nonzero(matcher)  # 统计判断正确的数量
accuracy = correct * 100.0 / result.size  # 计算准确率
print("当前使用KNN识别手写数字的准确率为:", accuracy)
# 当前使用KNN识别手写数字的准确率为: 91.64

四、传入单个图像,使用该模型进行识别

  • 所使用的库在最开始统一导入过了

图像:

  • 用的是20*20像素的,所以看起来很小        

1.导入图像

img_one = cv2.imread('test000.png')  # 导入图像

2.处理成灰度图

gray_one = cv2.cvtColor(img_one,cv2.COLOR_BGR2GRAY)  # 变成灰度图

3.获取数据并转换成数组

  • 因为这里使用的是单个图像,数据直接转换成数组即可
cells = np.array(gray_one)   # 获取数据 转换成数组
print(cells.shape)           # 查看数组维度 (20, 20)

4.将数据变成KNN模型可使用的维度

text_one = cells.reshape(-1,400).astype(np.float32)   # 将数据变成knn模型可使用的维度
print(text_one.shape)           # (1, 400)

5.进行图像识别

ret,result,neighbours,dist = knn.findNearest(text_one,k=11)
print(result)  # [[0.]] 输入图片为0 识别结果为0 识别成功

总结

KNN图像识别步骤:

1.导入所需库

2.导入图像并处理成数据 

        这是个难点,这次使用的数据是工整数据所以还没感觉到,但是在机器学习里获取数据集占一大部分的工作量

3.获取特征数据集

4.获取标签数据集

5.创建KNN模型并训练

6.进行测试

标签:KNN,图像识别,--,cv2,train,图像,np,20
From: https://blog.csdn.net/weixin_65047977/article/details/141269356

相关文章

  • leetcode面试经典150题-13. 罗马数字转整数
    https://leetcode.cn/problems/roman-to-integer/description/?envType=study-plan-v2&envId=top-interview-150 GOpackageleetcode150import"testing"/*romanMap:=map[string]int{"I":1,"V":......
  • 2024.8.16 总结(集训)
    今天是[whx](?)巨佬来给我们讲数论,大概是狄利克雷卷积、莫比乌斯反演、杜教筛、PN筛这条线路。虽然我很喜欢莫反,之前写了一些莫反题,但今天还是很有收获。对整除分块、杜教筛的理解更深刻了(关于整除分块为什么是\(O(\sqrtn)\)的、杜教筛的本质)。明白了\(\mu\)适合容斥。见到......
  • 手机点灯控制ESP8266板载LED
    #defineBLINKER_PRINTSerial#defineBLINKER_WIFI#include<Blinker.h>charauth[]="c9876669831c";//上一步中在app中获取到的SecretKeycharssid[]="ChinaNet-Ks22";//您的WiFi热点名称charpswd[]="12345678";//您的WiFi密码#include......
  • PbootCMS常用 if 判断
    1.导航高亮{pboot:if('[nav:scode]'=='{sort:tcode}')}class="active"{/pboot:if}//用于非首页例:{pboot:nav}<li{pboot:if('[nav:scode]'=='{sort:tcode}')}class="active"{/pboot:if}><ahref="......
  • PbootCMS用于调导航菜单栏目列表,对应后台的“基础内容>内容栏目”
    适用范围:全站任意地方均可使用标签作用:用于调导航菜单栏目列表,对应后台的“基础内容>内容栏目”教程新增加pbootcms导航栏logo居中判断案例1、导航菜单列表{pboot:nav}<ahref="[nav:link]">[nav:name]</a>{/pboot:nav}控制参数:num=*数量,非必填,用于控制输出的数量parent=......
  • PbootCMS用于调取网站的基本配置信息,对应后台的“基础内容>站点信息”
    适用范围:全站任意地方均可使用标签作用:用于调取网站的基本配置信息,对应后台的“基础内容>站点信息”{pboot:siteindex}站点入口地址,用于地址前置引用{pboot:sitepath}站点路径,根目录时值为空{pboot:sitelanguage}站点语言{pboot:sitetitle}站点标题{pboot......
  • PbootCMS输出当前栏目的相关信息
    {sort:tcode}当前栏目的顶级栏目编码{sort:topname}当前栏目的顶级栏目名称{sort:toplink}当前栏目的顶级栏目链接{sort:pcode}当前栏目的父栏目编码{sort:parentname}当前栏目的父栏目名称{sort:parentlink}当前栏目的父栏目链接{sort:scode}当前......
  • 后端工具包(个人版)
    功能:1、实体类敏感字段脱敏功能,支持:实体对象及list<实体对象>。 使用:1、字段脱敏功能 1.1jar包下载导入 1.2开启aop注解扫描,以及扫描自己的工具包。 1.3 在controller的方法上添加@DesensitizationInterface注解,注:返回类型为实体类或list<实体类>形式。 1.4......
  • 一文快速了解开源表单快速开发的多个优势
    帮助企业提升效率、降低成本、做好数据治理,是低代码技术平台的发展优势。了解低代码技术平台的客户朋友都知道,它拥有可视化操作界面、更高效、更可靠、更灵活等优势,是助力企业降本增效的助手。本文将从各个方面为大家解析什么是低代码技术平台,以及开源表单快速开发的优势特点。先......
  • Java 如何判断map为null或者空
    1.示例一在Java中,如果我们想判断一个Map是否为null或者空(即没有任何键值对),我们可以使用以下的方法。下面是一个完整的示例代码,展示了如何进行这样的判断:importjava.util.HashMap;importjava.util.Map;publicclassMapNullOrEmptyCheck{publicstaticvoidm......