opencv进阶06-基于K邻近算法识别手写数字示例

这篇具有很好参考价值的文章主要介绍了opencv进阶06-基于K邻近算法识别手写数字示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

opencv 中 K 近邻模块的基本使用说明及示例

在 OpenCV 中,不需要自己编写复杂的函数实现 K 近邻算法,直接调用其自带的模块函数即可。本节通过一个简单的例子介绍如何使用 OpenCV 自带的 K 近邻模块。

本例中有两组位于不同位置的用于训练的数据集,如图 20-14 所示。两组数据集中,一组位于左下角;另一组位于右上角。随机生成一个数值,用 OpenCV 中的 K 近邻模块判断该随机数属于哪一个分组。

opencv进阶06-基于K邻近算法识别手写数字示例,opencv 进阶,计算机视觉,人工智能,opencv,算法,人工智能
上述两组数据中,位于左下角的一组数据,其 x、y 坐标值都在(0, 30)范围内。位于右上角的数据,其 x、y 坐标值都在(70, 100)范围内。

根据上述分析,创建两组数据,每组包含 20 对随机数(20 个随机数据点):

rand1 = np.random.randint(0, 30, (20, 2)).astype(np.float32)
rand2 = np.random.randint(70, 100, (20, 2)).astype(np.float32)
  • 第 1 组随机数 rand1 中,其 x、y 坐标值均位于(0, 30)区间内。
  • 第 2 组随机数 rand2 中,其 x、y 坐标值均位于(70, 100)区间内。
    接下来,为两组随机数分配标签:
  • 将第 1 组随机数对划分为类型 0,标签为 0。
  • 将第 2 组随机数对划分为类型 1,标签为 1。

然后,生成一对值在(0, 100)内的随机数对:

test = np.random.randint(0, 100, (1, 2)).astype(np.float32)

示例:使用 OpenCV 自带的 K 近邻模块判断生成的随机数对 test 是属于 rand1 所在的类型0,还是属于 rand2 所在的类型 1。

import cv2
import numpy as np
import matplotlib.pyplot as plt
# 用于训练的数据
# rand1 数据位于(0,30)
rand1 = np.random.randint(0, 30, (20, 2)).astype(np.float32)
# rand2 数据位于(70,100)
rand2 = np.random.randint(70, 100, (20, 2)).astype(np.float32)
# 将 rand1 和 rand2 拼接为训练数据
trainData = np.vstack((rand1, rand2))
# 数据标签,共两类:01
# r1Label 对应着 rand1 的标签,为类型 0
r1Label=np.zeros((20,1)).astype(np.float32)
# r2Label 对应着 rand2 的标签,为类型 1
r2Label=np.ones((20,1)).astype(np.float32)
tdLable = np.vstack((r1Label, r2Label))
# 使用绿色标注类型 0
g = trainData[tdLable.ravel() == 0]
plt.scatter(g[:,0], g[:,1], 80, 'g', 'o')
# 使用蓝色标注类型 1
b = trainData[tdLable.ravel() == 1]
plt.scatter(b[:,0], b[:,1], 80, 'b', 's')
# plt.show()
# test 为用于测试的随机数,该数在 0100 之间
test = np.random.randint(0, 100, (1, 2)).astype(np.float32)
plt.scatter(test[:,0], test[:,1], 80, 'r', '*')
# 调用 OpenCV 内的 K 近邻模块,并进行训练
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, tdLable)
# 使用 K 近邻算法分类
ret, results, neighbours, dist = knn.findNearest(test, 5)
# 显示处理结果
print("当前随机数可以判定为类型:", results)
print("距离当前点最近的 5 个邻居是:", neighbours)
print("5 个最近邻居的距离: ", dist)
# 可以观察一下显示,对比上述输出
plt.show()

运行结果:

当前随机数可以判定为类型: [[1.]]
距离当前点最近的 5 个邻居是: [[1. 1. 1. 1. 1.]]
5 个最近邻居的距离:  [[  5.  17. 113. 136. 178.]]

opencv进阶06-基于K邻近算法识别手写数字示例,opencv 进阶,计算机视觉,人工智能,opencv,算法,人工智能
从图中可以看出,随机点(星号点)距离右侧小方块(类型为 1)的点更近,因此被判定为属于小方块的类型 1。

示例:使用 OpenCV 自带的函数完成对手写数字的识别

图片集在05 节中有下载地址

import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取样本(特征)图像的值
s='image_number\\' # 图像所在的路径
num=100 # 共有的样本数量

row=240 # 特征图像的行数
col=240 # 特征图像的列数
a=np.zeros((num,row,col)) # 存储所有样本的数值

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) # 看看特征值的形状是什么样子
#print(row) # 看看 row 的值,有多少个特征值(100
# 从 0 开始,到 num-1 结束,每次加 1,
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 处理为单行形式,并转换为 float32 类型,以便后面的 kNN 算法使用
train = feature[:,:].reshape(-1,round(row/5)*round(col/5)).astype(np.float32)

print(train.shape)
# 贴标签,要注意,是 range(0,100)而非 range(0,101)
train_labels = [int(i/10) for i in range(0,100)]
train_labels = np.asarray(train_labels)
test_labels = train_labels.copy()
#print(*trainLabels) # 打印测试看看标签值
##读取图像值,并提取特征,以便后面的 kNN 算法使用,这里只读取一个图像,即待识别图像,所以只有一个特征值,即 test
o=cv2.imread('image_number\\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
# 将 of 处理为单行形式,并转换为 float32 类型,以便后面的 kNN 算法使用
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, train_labels)

ret,result,neighbours,dist = knn.findNearest(test,k=5)

print("当前随机数可以判定结果是:", str(result[0][0]))
print("距离当前点最近的 5 个邻居是:", neighbours)
print("5 个最近邻居的距离: ", dist)


运行结果:

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

咂一看,哎呦!结果还挺准,然后再测试下其他的数字图片呢?

o=cv2.imread('image_number\\test\\6.bmp',0) # 读取待识别图像

再看下效果,

当前随机数可以判定结果是: 1.0
距离当前点最近的 5 个邻居是: [[6. 1. 1. 1. 1.]]
5 个最近邻居的距离:  [[90739. 92107. 92312. 92652. 93016.]]

连续改了几个,发现识别准备度还是很低的。

示例:接下来我们借用MNIST数据集再次来验证下。

第一步:下载数据集,训练模型,保存模型到本地

代码如下:

import cv2
import numpy as np
from keras.datasets import mnist


if __name__ == '__main__':
    # 直接使用Keras载入的训练数据(60000, 28, 28) (60000,)
    (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
    # 变换数据的形状并归一化
    train_images = train_images.reshape(train_images.shape[0], -1)  # (60000, 784)
    train_images = train_images.astype('float32') / 255

    test_images = test_images.reshape(test_images.shape[0], -1)
    test_images = test_images.astype('float32') / 255

    print(test_images)
    # 将标签数据转为float32
    train_labels = train_labels.astype(np.float32)
    test_labels = test_labels.astype(np.float32)

    # 传入knn的训练数据形状为(60000, 784) 训练标签为(60000,)

    # 创建knn对象
    knn = cv2.ml.KNearest_create()
    # 设置k值 默认的k=10
    knn.setDefaultK(5)
    # 设置是分类还是回归
    knn.setIsClassifier(True)


    # 开始训练,训练数据的形状为(60000, 784) 训练标签为(60000,),训练数据必须是float32类型,标签必须是int32类型,并且标签必须是单通道,不能是多通道,否则会报错
    knn.train(train_images, cv2.ml.ROW_SAMPLE, train_labels)

    # 手写数字识别保存的knn模型非常大 有两百多兆
    knn.save('mnist_knn.xml')

    # 进行模型准确率的测试 结果是一个元组 第一个值为数据1的结果
    test_pre = knn.predict(test_images)
    test_ret = test_pre[1]

    # 计算准确率
    test_ret = test_ret.reshape(-1, )
    test_sum = (test_ret == test_labels)
    print(test_sum)
    acc = test_sum.mean()
    print(acc)

验证模型:

import cv2
import numpy as np

if __name__=='__main__':
    #读取图片
    img=cv2.imread('D:\\ai\\test\\6.png', 0)  # 读取待识别图像

    #重新设置图片大小
    img=cv2.resize(img,(28,28))

    cv2.imshow('img',img)

    img_sw=img.copy()

    #将数据类型由uint8转为float32
    img=img.astype(np.float32)
    #图片形状由(28,28)转为(784,)
    img=img.reshape(-1,)
    #增加一个维度变为(1,784)
    img=img.reshape(1,-1)
    #图片数据归一化
    img=img/255
    #载入knn模型
    knn=cv2.ml.KNearest_load('mnist_knn.xml')

    #进行预测
    img_pre=knn.predict(img)

    print('img_pre:',img_pre)

    print(img_pre[0])

    cv2.waitKey()
    cv2.destroyAllWindows()



运行结果:

opencv进阶06-基于K邻近算法识别手写数字示例,opencv 进阶,计算机视觉,人工智能,opencv,算法,人工智能
这里测试的图片是mnist 数据集中的,这个数据集下载的是压缩的,如要验证需要从下面的图片中去截图单独保存下来自己验证。总体准确率还是比较高的。**但是如果是自己随便画个数字再来验证 准备率就比较低了。**感兴趣的朋友可以自己多试试。

显示下面图片的代码

import cv2
import numpy as np
from keras.datasets import mnist
from matplotlib import pyplot as plt

# 加载数据
(train_dataset, train_labels), (test_dataset, test_labels) = mnist.load_data()
train_labels = np.array(train_labels, dtype=np.int32)
# 打印数据集形状
print(train_dataset.shape, test_dataset.shape)
# 图像预览
for i in range(40):
    plt.subplot(4, 10, i+1)
    plt.imshow(train_dataset[i], cmap='gray')
    plt.title(train_labels[i], fontsize=10)
    plt.axis('off')
plt.show()

opencv进阶06-基于K邻近算法识别手写数字示例,opencv 进阶,计算机视觉,人工智能,opencv,算法,人工智能

缺点:模型文件大,识别速度慢文章来源地址https://www.toymoban.com/news/detail-652740.html

到了这里,关于opencv进阶06-基于K邻近算法识别手写数字示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手写数字识别-基于卷积神经网络

    🌞欢迎来到机器学习的世界  🌈博客主页:卿云阁  💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🌠本阶段属于练气阶段,希望各位仙友顺利完成突破 📆首发时间:🌹2021年6月5日🌹 ✉️希望可以和大家一起完成进阶之路! 🙏作者水平很有限,如果发

    2024年02月10日
    浏览(45)
  • CNN卷积神经网络实现手写数字识别(基于tensorflow)

    卷积网络的 核心思想 是将: 局部感受野 权值共享(或者权值复制) 时间或空间亚采样 卷积神经网络 (Convolutional Neural Networks,简称: CNN )是深度学习当中一个非常重要的神经网络结构。它主要用于用在 图像图片处理 , 视频处理 , 音频处理 以及 自然语言处理 等等。

    2024年02月11日
    浏览(43)
  • 【深度学习实战—1】:基于Keras的手写数字识别(非常详细、代码开源)

    ✨博客主页:王乐予🎈 ✨年轻人要:Living for the moment(活在当下)!💪 🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】    本来想着多更新一些关于深度学习的文章,但这方面知识专业度很高,如果作者本身都掌握不好,又怎么能写出好文章分享

    2024年02月07日
    浏览(43)
  • [深度学习实战]基于PyTorch的深度学习实战(下)[Mnist手写数字图像识别]

    PyTorch——开源的Python机器学习库   首先感谢所有点开本文的朋友们!基于PyTorch的深度学习实战可能要告一段落了。本想着再写几篇关于 PyTorch神经网络深度学习 的文章来着,可无奈项目时间紧任务重,要求 短时间内出图并做好参数拟合 。所以只得转战 Matlab 编程,框架旧

    2024年02月16日
    浏览(55)
  • 基于python的Keras库构建的深度神经网络手写数字识别模型

    目录 模型训练过程 ①导入所需的库 ②加载手写体数据集,将数据集分为训练集和测试集 ③数据预处理 ④构建模型 ⑤编译模型 ⑥训练模型 ⑦使用测试集进行验证 ⑧输出模型准确率和时间消耗 完整代码如下: 模型训练过程 使用到的数据集为IMDB电影评论情感分类数据集,该

    2024年02月09日
    浏览(44)
  • 入门深度学习——基于全连接神经网络的手写数字识别案例(python代码实现)

    1.1 问题导入 如图所示,数字五的图片作为输入,layer01层为输入层,layer02层为隐藏层,找出每列最大值对应索引为输出层。根据下图给出的网络结构搭建本案例用到的全连接神经网络 1.2 手写字数据集MINST 如图所示,MNIST数据集是机器学习领域中非常经典的一个数据集,由6

    2024年02月03日
    浏览(46)
  • 人工智能概论报告-基于PyTorch的深度学习手写数字识别模型研究与实践

    本文是我人工智能概论的课程大作业实践应用报告,可供各位同学参考,内容写的及其水,部分也借助了gpt自动生成,排版等也基本做好,大家可以参照。如果有需要word版的可以私信我,或者在评论区留下邮箱,我会逐个发给。word版是我最后提交的,已经调整统一了全文格

    2024年02月05日
    浏览(74)
  • 基于深度学习的手写数字识别项目GUI(Deep Learning Project – Handwritten Digit Recognition using Python)

    一步一步教你建立手写数字识别项目,需要源文件的请可直接跳转下边的链接:All project 在本文中,我们将使用MNIST数据集实现一个手写数字识别应用程序。我们将使用一种特殊类型的深度神经网络,即卷积神经网络。最后,我们将构建一个GUI,您可以在其中绘制数字并立即

    2024年02月11日
    浏览(38)
  • 手写数字识别(识别纸上手写的数字)

    说明 使用pytorch框架,实现对MNIST手写数字数据集的训练和识别。重点是,自己手写数字,手机拍照后传入电脑,使用你自己训练的权重和偏置能够识别。数据预处理过程的代码是重点。 分析 要识别自己用手在纸上写的数字,从特征上来看,手写数字相比于普通的电脑上的数

    2024年02月03日
    浏览(40)
  • [学习笔记] [机器学习] 10. 支持向量机 SVM(SVM 算法原理、SVM API介绍、SVM 损失函数、SVM 回归、手写数字识别)

    视频链接 数据集下载地址:无需下载 学习目标: 了解什么是 SVM 算法 掌握 SVM 算法的原理 知道 SVM 算法的损失函数 知道 SVM 算法的核函数 了解 SVM 算法在回归问题中的使用 应用 SVM 算法实现手写数字识别器 学习目标: 了解 SVM 算法的定义 知道软间隔和硬间隔 在很久以前的

    2024年02月09日
    浏览(91)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包