《机器学习》KNN算法搭配OpenCV训练模型、识别图片 No.2

news2024/12/25 23:43:06

一、使用KNN算法识别数字

1、明确目的:

        有一张图片,其中有一份数据,其中共有0-9的不同写法的数字,共5000条,现在想要对这张图片中的数据进行训练,以完成当输入一张图片,图片内为手写的数字,能自动识别其数字的值为多少,从而完成训练。

2、获取数据

首先看下面一张图:

它的像素点为1000 x 2000,其中长有100个数据。宽有50个数据,共5000个数据 

可能你看不清楚什么样的,那么不妨方法一下,其竖直方向排布如下:

  

3、明确操作流程

        首先导入这张图片,将这张图片转换成灰度图(3.1解析灰度图),然后将这张图片中的每个数字提取出来,这张图片中的每个数字都是由20x20=400个像素点组成,将这每一个单独的数字存放的列表中,然后将列表使用np.reshape()函数转换成二维数组的形式,以便于后面的切分操作。

        对存放所有数据的二维数组进行切分,前一半当做训练集后一半当做测试集,这张图中0-9对应的每个数字都为5行100列,成上下排布,我们只对列作切半处理,不对行进行切分,由此来得到训练集和测试集的数据,但是这个数据还不能直接拿来训练,还需要将每单个数字中的20x20的像素点转变成一行,此时可以使用np.reshape()将其转变成1x400像素值的状态,以便于对其进行训练和测试。

        接下来有了训练集和测试集,但是却没有标签集,此时可以生成一个0-9的数组,然后因为训练集中每个单个数据都有250个,即一共2500个,那么就要设置2500个标签用来对应这2500个数字,即可以使用np.repeat()来将0-9每个数字都复制250遍,然后再使用np.newaxis将这个一维数组生高成二维数组,以满足和训练集同样的维度。

        最后就是开始训练数据了,这里使用OpenCV中的包cv2.ml的方法KNearest_Create() 创建一个knn算法的分类器对象,并对其进行初始化,然后导入训练集以及训练标签,并使用cv2.ml.ROW_SAMPLE表示对每一行数据进行训练,接下来就是导入数据进行测试,使用knn.finNearest()导入数据并指定邻居个数,返回四个值ret、result、neighbours、dist,其解释在下列3.2。此时即完成全流程的解说。

3.1 什么是灰度图

        灰度图是一种图像的表示方式,相比于彩色图像,灰度图仅包含一个灰度通道,即每个像素只有一个灰度级灰度级通常用一个8位整数表示,范围从0(黑色)到255(白色)表示不同的亮度值

        在灰度图中,每个像素表示图像中某一点的亮度级别。亮度级别越,该点在图像中就越;亮度级别越,该点在图像中就越。因此,灰度图能够表示图像的明暗程度

        灰度图常用于图像处理领域和计算机视觉任务中。通过对灰度图进行处理,可以实现诸如图像增强、边缘检测、目标检测、人脸识别等功能。例如,对于目标检测任务,可以将灰度图作为输入,通过检测明暗程度变化或者轮廓来识别目标物体。

        为了生成灰度图,可以将彩色图像转换为灰度图。一种常见的方法是使用加权平均法,根据红色、绿色和蓝色通道的亮度对应比例,计算出每个像素的灰度值。另外,还可以使用其他方法,如取最大值、取最小值等来生成灰度图。例如可以使用OpenCV中的方法:

import cv2

# 读取彩色图像
image = cv2.imread('color_image.jpg')

# 转换为灰度图
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 显示灰度图
cv2.imshow('Gray Image', gray_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

         在以上代码中,首先使用cv2.imread()函数读取彩色图像,将图像保存在image变量中。然后,使用cv2.cvtColor()函数将彩色图像转换为灰度图,将灰度图保存在gray_image变量中。最后,使用cv2.imshow()函数显示灰度图窗口,并通过cv2.waitKey()和cv2.destroyAllWindows()函数等待关闭窗口。

        注意,cv2.COLOR_BGR2GRAY参数表示将BGR格式的图像转换为灰度图。如果你的图像不是BGR格式,你可能需要根据实际情况选择不同的颜色空间转换函数。

3.2 ret、result、neighbours、dist 解析
  • ret: 返回值,表示操作是否成功(通常是 0 表示成功)。
  • result: 每个测试样本的预测标签。是对 test_new 中每一行数据的预测结果。
  • neighbours: 最近邻的标签的矩阵,表示每个测试样本的最近 K 个邻居的标签。
  • dist: 最近邻的距离矩阵,表示每个测试样本到其最近 K 个邻居的距离。

4、代码实现

4.1 导包
#后面等于号为指定版本号,防止和有些包使用发生冲突
pip install opencv_python==3.4.17.61
4.2 完整代码如下:
import numpy as np
import cv2

# 导入图片
img = cv2.imread('digits.png')
# 将图片转化成灰度图
grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 将这个图片中的每一个数字分隔出来然后插入列表
cells = []
for row in np.vsplit(grey,50):
    cells.append(np.hsplit(row,100))

# 将列表数据转化成矩阵类型
x = np.array(cells)

# 取前一半数据当做训练集,后一半数据当做测试集
# 取出矩阵x的行列,行为所有的行,列为0到50列,但是不包含第50列,当做训练集
train = x[:,:50]
# 即所有的行,以及后50列
test = x[:,50:100]

# 将每一个数字数据的像素点由20x20像素的转换成1*400像素的,即转换成一行像素点数据
# -1为自动判断样本数
train_new = train.reshape(-1,400).astype(np.float32)
test_new = test.reshape(-1,400).astype(np.float32)

# 定义标签列,便签值为0~9,将其生成一个0-9的数组
y = np.arange(10)
# 将0-9的一维数组中的每个元素复制250次得到一个新的一维数组,其内有10x250个数据
labels = np.repeat(y,250)
# 将上述充满0-9数字的2500条数据的一维数组,增加其维度到二维数组,即每单个值为一个一维数组
train_label = labels[:,np.newaxis]
test_label = np.repeat(y,250)[:,np.newaxis]

# 使用OpenCV中的包cv2.ml的用法KNearest_create创建一个knn分类器对象,用于初始化模型
knn = cv2.ml.KNearest_create()
# cv2.ml.ROW_SAMPLE表示每一行的数据,即导入train_new的每一行数据用来训练,同时插入标签列train_label
knn.train(train_new,cv2.ml.ROW_SAMPLE,train_label)

# 导入测试数据进行测试,并指定最近邻的个数为5,其返回值为ret:表示测试的正确性,正确返回1,错误返回0,result返回测试结果,
# neighbors 表示最近邻的标签的矩阵,表示每个测试样本的最近k个邻居的标签
# dist 表示每个测试样本到其最近k个令居的距离
ret,result,neighbours,dist = knn.findNearest(test_new,k=5)
print(result)

# 判断语句,判断测试结果是否与测试数据的标签相等,返回true或false
maches = result==test_label
# 统计非空数据的和,表示判断为1的个数
count = np.count_nonzero(maches)
# 计算正确率,即为1的个数除以测试结果的总条数
person = count*100/len(result)
print(person)

二、手写数字进行识别

1、在画图板中手绘数字

如下图所示流程:

2、实操代码

import numpy as np
import cv2

img = cv2.imread('digits.png') # 导入图片数据
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 转变为灰度图

cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)] #将 每个数字都存放到列表中

x = np.array(cells) # 将数据转换成矩阵类型

train = x[:,:] #将整个图片的数据当做训练集

train_new = train.reshape(-1,400).astype(np.float32) # 将每单个数据对应的像素点转变成一行的状态

k = np.arange(10)
labels = np.repeat(k,500)
train_labels = labels[:,np.newaxis]

knn = cv2.ml.KNearest_create()  # 创建一个knn分类器,并初始化模型
knn.train(train_new,cv2.ml.ROW_SAMPLE,train_labels) # 导入数据进行训练

testt = cv2.imread('4.png')   # 导入刚刚保存的图片
gray2 = cv2.cvtColor(testt,cv2.COLOR_BGR2GRAY) # 将图片转变成灰度图
x1 = np.array(gray2) # 将数据转变成矩阵类型
test_new1 = x1.reshape(-1,400).astype(np.float32)  # 将每个数据转变成单独的一行

ret,result,neighbours,dist = knn.findNearest(test_new1,k=3)  # 将数据输入进行测试
print(result)

测试结果为:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MaxKB(三):通过修改代码去掉社区版限制

由于社区版对创建用户、创建应用、创建知识库等功能有数量显示,既然咱们都有源码了,那限制能否解除呢,经过尝试是可以的。 首选源代码需要能运行起来,具体见《MaxKB(二):Ubuntu24.04搭建maxkb开…

暑假算法刷题日记 Day 10

目录 重点整理 054、 拼数 题目描述 输入格式 输出格式 输入输出样例 核心思路 代码 055、 求第k小的数 题目描述 输入格式 输出格式 输入输出样例 核心思路 代码 总结 这几天我们主要刷了洛谷上排序算法对应的一些题目,相对来说比较简单 一共是13道…

数据埋点系列 18| 数据驱动产品开发:用洞察力塑造卓越产品

在当今竞争激烈的市场中,数据驱动的产品开发已成为创造成功产品的关键。通过利用数据洞察,公司可以更准确地了解用户需求,做出更明智的产品决策,并持续优化产品性能。本文将探讨如何在产品开发的各个阶段应用数据驱动方法。 目录…

python发邮件

1. SMTP(简单邮件传输协议)基础 SMTP 协议概述 SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)是用于在计算机网络上传输电子邮件的标准通信协议。它定义了发送邮件的基本规则和流程,确保邮件从发…

开源前端埋点监控插件Web-Tracing

Web-Tracing是一款专为前端项目设计的前端监控插件,它基于JavaScript设计,兼容跨平台使用,并提供了全方位的监控功能。 开源地址:https://gitee.com/junluoyu/web-tracing-analysis 以下是关于Web-Tracing的详细介绍:…

李沐:创业一年,人间三年

大家好,我是 Bob! 😊 一个想和大家慢慢变富的 AI 程序员💸 分享 AI 前沿技术、项目经验、面试技巧! 欢迎关注我,一起探索,一起破圈!💪 李沐:创业一年,人间三年 前不久&am…

【项目】Java文档搜索引擎测试报告

一、项目背景 随着Java技术的不断发展和广泛应用,Java开发者对于API文档的需求日益增加。高质量的API文档不仅能帮助开发者快速了解和掌握各种类、接口、方法等的功能与用法,还能显著提升开发效率。然而,在面对庞大的API文档集时&#xff0c…

爱心公益,向阳而生 ——共同家园 “向阳计划“温暖启航

“向阳计划”由大湾区共同家园线上运营建设共同家园社区公益团队。在这个快节奏的时代,总有一份温暖,能穿透喧嚣,照亮人心。今天,共同家园社区我们满怀激动与期待,正式推出“向阳计划”——一项旨在汇聚社会各界爱心力量,共同为需要帮助的人群送去光明与希望的公益行动。我们共…

鸿蒙 点击获取电话号拨打电话 @ohos.telephony.call (拨打电话)

1, 先看看效果 2, 直接CV 代码 import call from ohos.telephony.callEntry Component struct Index {Statephoto: string 15517189270build() {Column() {Row() {Text(this.photo)Image($r(app.media.ic_contacts_incoming_filled)).width(30).height(30).fillColor(Color.Or…

Ajax笔记总结:第二天(Ajax完结)

Xmind鸟瞰图: 简单文字总结: ajax知识总结: Ajax的基本语法: 1.定义一个实例化对象:new XMLHttpRequest() 2.调用open方法填写请求方式和请求地址 3.调用send方法发送请求 4.监听请求状态 5.4代…

05 serv00安装typecho

下载 ‍ cd domain/xxx.serv00.net/# 下载typecho git clone https://github.com/typecho/typecho.git# 当前有两个目录 typecho/ 和 public_html/ ls# 替换html rm -rf public_html/ mv typecho public_html‍ 安装 浏览器访问你的网站 xxx.serv0.net,看见 type…

informer中的WorkQueue机制的实现分析与源码解读(3)之限速队列RateLimitingQueue

概述 前面2篇文章介绍了workqueue中的普通队列FIFO和延时队列。接下来我们分析workqueue中的第三种队列: 限速队列 client-go 的 util/workqueue 包里主要有三个队列,分别是普通队列Queue,延时队列DelayingQueue,限速队列RateLimitingQueue…

IDEA:如何在idea中设置自动导包

这里使用的是idea2020版本,但是不同版本操作不会有较大的差别. 在Editer中展开General之后,选中Auto Import,最后勾选中Add unambiguous imports on the fly.

pygame开发课程系列(7):打砖块,飞行射击,跳跃游戏实例开发

第七章 实践项目 在本章中,我们将通过三个实践项目来巩固和应用前面章节中学到的知识。这些项目涵盖了经典打砖块游戏、飞行射击游戏和简单的平台游戏,它们将帮助你更好地理解 Pygame 的使用,并为你开发自己的游戏提供灵感和实践经验。 7.1…

Java毕业论文 【二手书电子商城网站】源码见github (原创项目,从0-1自己实现)

文章目录 项目背景主要功能模块分布模块分布具体部分功能 系统架构功能演示买家部分界面:卖家部分界面【8002模块】:管理员部分界面: 项目github地址 项目背景 主要面向高校学生,将高年级同学的书回收到低年级学生的手上&#xf…

EmguCV学习笔记 C# 5.2 仿射变换

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)

教程简介 EasySQLite是一个七天.NET 8操作SQLite入门到实战详细教程,主要是对学校班级,学生信息进行管理维护(包含选型、开发、发布、部署)! 什么是SQLite? SQLite 是一个软件库,实现了自给自…

【蓝牙协议栈】【BLE】精讲引用(包含)服务(Included service)

1.欢迎大家关注和订阅匠心之作,【精讲蓝牙协议栈】、【精讲BLE协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待! 2. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OP…

【安全靶场】-DC-8

❤️博客主页: iknow181 🔥系列专栏: 网络安全、 Python、JavaSE、JavaWeb、CCNP 🎉欢迎大家点赞👍收藏⭐评论✍ 目标:192.168.216.150 一、收集信息 1.端口扫描 nmap -T4 -A 192.168.216.150 -p- 看到80端…

【comfyui 】comfyui mac配置教程

comfyui mac配置教程 1. 安装工程依赖与环境配置2. 安装Comfyui3. Comfyui模型下载与运行 1. 安装工程依赖与环境配置 首先,我们找到Mac电脑的终端并打开,我们复制下列代码并粘贴到终端,然后回车,即可开始安装Xcode工具。 xcode…