通过识别手写的数字来练习KNN算法。再OpenCV中,可以直接调用cv2.KNearest()来实现K邻近算法。

本文目录:

整体流程

数据初始化

  • 特征图像保存在image路径下
  • 特征值一共有100个(0~9,每个数字有10个)
  • 特征图像的行数(高度)、列数(宽度)。可以通过程序读取。在本例中,已经设置好了,是固定的特征,长和宽都是240行。
#读取样本(特征)图像的值
s='image\\'  #图像所在路径
num=100 #共有样本数量
row=240 #每个数字图像的行数
col=240 #每个数字图像的列数
a=np.zeros((num,row,col)) #用来存储所有样本的数值

训练的图集

读取特征图像

将所有的特征图像读到变量a中,共有10个数字.可以采用嵌套循环来完成。

n=0 #用来存储当前图像的编号。
for i in range(0,10):
    for j in range(1,11):
        a[n,:,:]=cv2.imread(s+str(i)+'\\'+str(i)+'-'+str(j)+'.bmp',0)
        n=n+1

提取图像的特征

提取特征值,可以是计算每个子块内黑色或白色像素点的个数。此处选用白色。

化成3X3,图像映射到特征值

这里,把每幅图都划分成5X5的小块块。

#提取样本图像的特征
feature=np.zeros((num,round(row/5),round(col/5))) #用来存储所有样本的特征值
#print(feature.shape)  #看看feature的shape长什么样子
#print(row)            #看看row的值,有多少个特征(100)个

for ni in range(0,num):
    for nr in range(0,row):
        for nc in range(0,col):
            if a[ni,nr,nc]==255:
                feature[ni,int(nr/5),int(nc/5)]+=1

f=feature   #简化变量名称
#将feature处理为单行形式
train = feature[:,:].reshape(-1,round(row/5)*round(col/5)).astype(np.float32) 

计算待识别图像的特征值

##读取图像值
o=cv2.imread('image\\test\\5.bmp',0) #读取待测图像
of=np.zeros((round(row/5),round(col/5))) #用来存储测试图像的特征值
for nr in range(0,row):
    for nc in range(0,col):
        if o[nr,nc]==255:
            of[int(nr/5),int(nc/5)]+=1

test=of.reshape(-1,round(row/5)*round(col/5)).astype(np.float32) 

调用识别函数计算距离

#调用函数识别
knn=cv2.ml.KNearest_create()
knn.train(train,cv2.ml.ROW_SAMPLE, trainLabels)
ret,result,neighbours,dist = knn.findNearest(test,k=5)

输出结果

print("当前随机数可以判定为类型:", result)
print("距离当前点最近的5个邻居是:", neighbours)
print("5个最近邻居的距离: ", dist)

演示


import cv2
import numpy as np
#读取样本(特征)图像的值
s='image\\'  #图像所在路径
num=100 #共有样本数量
row=240 #每个数字图像的行数
col=240 #每个数字图像的列数
a=np.zeros((num,row,col)) #用来存储所有样本的数值
#print(a.shape)
n=0 #用来存储当前图像的编号。
for i in range(0,10):
    for j in range(1,11):
        a[n,:,:]=cv2.imread(s+str(i)+'\\'+str(i)+'-'+str(j)+'.bmp',0)
        n=n+1

#提取样本图像的特征
feature=np.zeros((num,round(row/5),round(col/5))) #用来存储所有样本的特征值
#print(feature.shape)  #看看feature的shape长什么样子
#print(row)            #看看row的值,有多少个特征(100)个


for ni in range(0,num):
    for nr in range(0,row):
        for nc in range(0,col):
            if a[ni,nr,nc]==255:
                feature[ni,int(nr/5),int(nc/5)]+=1
f=feature   #简化变量名称
#将feature处理为单行形式
train = feature[:,:].reshape(-1,round(row/5)*round(col/5)).astype(np.float32) 
#print(train.shape)
#贴标签,需要注意range(0,100)不是range(0,101)
trainLabels = [int(i/10)  for i in range(0,100)]
trainLabels=np.asarray(trainLabels)
#print(*trainLabels)   #打印测试看看标签值
##读取图像值
o=cv2.imread('image\\test\\5.bmp',0) #读取待测图像
of=np.zeros((round(row/5),round(col/5))) #用来存储测试图像的特征值
for nr in range(0,row):
    for nc in range(0,col):
        if o[nr,nc]==255:
            of[int(nr/5),int(nc/5)]+=1

test=of.reshape(-1,round(row/5)*round(col/5)).astype(np.float32) 
#调用函数识别
knn=cv2.ml.KNearest_create()
knn.train(train,cv2.ml.ROW_SAMPLE, trainLabels)
ret,result,neighbours,dist = knn.findNearest(test,k=5)
print("当前随机数可以判定为类型:", result)
print("距离当前点最近的5个邻居是:", neighbours)
print("5个最近邻居的距离: ", dist)

结果:

当前随机数可以判定为类型: [[5.]]
距离当前点最近的5个邻居是: [[5. 3. 5. 3. 5.]]
5个最近邻居的距离: [[77185. 78375. 79073. 79948. 82151.]]

图集下载

点击下载图集,链接失效请留言


博主个人公众号
版权声明 ▶ 本网站名称:陶小桃Blog
▶ 本文链接:https://www.52txr.cn/2022/CVKNN3.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!

最后修改:2022 年 05 月 25 日
如果觉得我的文章对你有用,请随意赞赏