opencv实现KNN算法识别图片数字

KNN算法实现识别图片数字

目录

  • KNN算法实现识别图片数字
    • 图片基本情况
      • 图片
      • 数据
    • 图片数字识别
      • 图片数据处理及预测
      • 其它数字图片正确率预测

图片基本情况


图片

数据

图片像素是2000x1000,即高(行)1000,宽(列)2000,每个数字区域为20*20,每5行都是同一个数字,每行数字有50个,每列数字有100个

图片数字识别


图片数据处理及预测

  • hsplit(矩阵,n)
    竖向切分切n个
  • vsplit(矩阵,n)
    横向切分切n个
  • reshape(-1,n)
    重构二维矩阵,-1表示所有,n表示列

400列即20*20每一个数字区域,每列为一个特征数据,占一个维度

  • astype(n)
    设置数据类型
  • cv2.ml.KNearest_create()
    创建knn算法
  • train(x,cv2.ml.ROW_SAMPLE,y)
    训练模型,x为特征数据,y为结果类别,cv2.ml.ROW_SAMPLE设置按行处理数据
  • ret,result,neighbors,dist = knn.findNearest(x,k=3)
    x为特征数据,k为范围,ret bool值,result数据预测结果,neighbors邻居,dist距离
  • 矩阵==矩阵
    返回矩阵,值为bool值,如果矩阵一一对应的值相等为T,否则F
  • np.count_nonzero(矩阵),计算为矩阵内非0的个数

代码展示:

python 复制代码
# 灰度图
img1 = cv2.imread('tu_data.png')
img = cv2.imread('tu_data.png',0)

# 每个数字区域为20*20,每5行都是同一个数字
# hsplit 竖向切分,vsplit 沿行横向切分
# 列表生成式,先横向切分切50行,再将横向行数据竖向切分,每行切100列,共50*100=5000个图片数据,每个都是一个1000/50=20,2000/100=20
#每个图片都是20*20的数值
cells = [np.hsplit(row,100) for row in np.vsplit(img,50)]
# print(cells)
# 列表转矩阵
data_img = np.array(cells)
# print(data_img)
# 切分数据一半,一半作为历史数据培训模型,一半作为测试数据,检测
# 切分后的是一半是5000/2=2500个,从中间竖切一半变为50*50
train_x = data_img[:,:50]
test_x = data_img[:,50:100]
# 设置x特征数据
tr_x = train_x.reshape(-1,400).astype(np.float32)
te_x = test_x.reshape(-1,400).astype(np.float32)
# 根据图片结果构建0-9的y类别标签
# 生成0-9的np矩阵
k = np.arange(10)
# 复制标签
# 从0到9,依次复制250个,50*5=250
lab = np.repeat(k,250)
# 增加数组维度
t_lab = lab[:,np.newaxis]
#创建knn算法
knn = cv2.ml.KNearest_create()
#训练模型
knn.train(tr_x,cv2.ml.ROW_SAMPLE,t_lab)
ret,result,neighbors,dist = knn.findNearest(te_x,k=3)
# 正确率
match = result==t_lab
T = np.count_nonzero(match)
c = T*100.0/ result.size
print(c)

运行结果:

其它数字图片正确率预测

其他图片为单个20*20的图片,如下

代码展示:

复制代码
import cv2
import numpy as np

# 只能是灰度图
img1 = cv2.imread('tu_data.png')
img = cv2.imread('tu_data.png',0)
# print(type(img1),type(img))
# 每个数字区域为20*20,每5行都是同一个数字
# hsplit 竖向切分,vsplit 沿行横向切分
# 列表生成式,先横向切分切50行,再将横向行数据竖向切分,每行切100列,共50*100=5000个图片数据,每个都是一个1000/50=20,2000/100=20
#每个图片都是20*20的数值
cells = [np.hsplit(row,100) for row in np.vsplit(img,50)]
# print(cells)
# 图片数据转np矩阵
data_img = np.array(cells)
# print(data_img)
# 切分数据一半,一半作为历史数据培训模型,一半作为测试数据,检测
# 切分后的是一半是5000/2=2500个,从中间竖切一半变为50*50
train_x = data_img[:,:50]
test_x = data_img[:,50:100]

# 设置x特征数据
tr_x = train_x.reshape(-1,400).astype(np.float32)
te_x = test_x.reshape(-1,400).astype(np.float32)
# 根据图片结果构建0-9的y类别标签
# 生成0-9的np矩阵
k = np.arange(10)
# 复制标签
# 从0到9,依次复制250个,50*5=250
lab = np.repeat(k,250)
# 增加数组维度
t_lab = lab[:,np.newaxis]
print(k,type(k))
print(lab,type(lab))
print(t_lab,type(t_lab))
# 创建knn算法
knn = cv2.ml.KNearest_create()
#训练模型
knn.train(tr_x,cv2.ml.ROW_SAMPLE,t_lab)
ret,result,neighbors,dist = knn.findNearest(te_x,k=3)


t1 = cv2.imread('t1.png',0)
t2 = cv2.imread('t2.png',0)
t3 = cv2.imread('t3.png',0)
t4 = cv2.imread('t4.png',0)
t5 = cv2.imread('t5.png',0)
t6 = cv2.imread('t6.png',0)
t7 = cv2.imread('t7.png',0)
t8 = cv2.imread('t8.png',0)
t9 = cv2.imread('t9.png',0)
t0 = cv2.imread('t0.png',0)
#运行都是np.array数组类型,需要添加定义为数组,再重构,可以先输出部分结果观察
tt = np.array([t0,t1,t2,t3,t4,t5,t6,t7,t8,t9])
k = np.array([0,1,2,3,4,5,6,7,8,9])
t_lab1 = k[:,np.newaxis]
tt = tt.reshape(-1,400).astype(np.float32)
# 不同数据输入可能输出结果与类型不同,判断标签可能需要调整
ret1,result1,neighbors1,dist1 = knn.findNearest(tt,k=3)
print(result1)
print(t_lab1)
match1 = result1==t_lab1
print(result1==t_lab1)
T1 = np.count_nonzero(match1)
c1 = T1*100.0/ result1.size
print(c1)

运行结果:

相关推荐
阿坡RPA41 分钟前
手搓MCP客户端&服务端:从零到实战极速了解MCP是什么?
人工智能·aigc
用户27784491049931 小时前
借助DeepSeek智能生成测试用例:从提示词到Excel表格的全流程实践
人工智能·python
机器之心1 小时前
刚刚,DeepSeek公布推理时Scaling新论文,R2要来了?
人工智能
算AI3 小时前
人工智能+牙科:临床应用中的几个问题
人工智能·算法
JavaEdge在掘金3 小时前
ssl.SSLCertVerificationError报错解决方案
python
我不会编程5554 小时前
Python Cookbook-5.1 对字典排序
开发语言·数据结构·python
凯子坚持 c4 小时前
基于飞桨框架3.0本地DeepSeek-R1蒸馏版部署实战
人工智能·paddlepaddle
老歌老听老掉牙4 小时前
平面旋转与交线投影夹角计算
python·线性代数·平面·sympy
满怀10154 小时前
Python入门(7):模块
python
无名之逆4 小时前
Rust 开发提效神器:lombok-macros 宏库
服务器·开发语言·前端·数据库·后端·python·rust