首页 > 编程语言 >《机器学习》KNN算法搭配OpenCV训练模型、识别图片 No.2

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

时间:2024-08-16 22:26:26浏览次数:14  
标签:KNN cv2 OpenCV train 灰度 No.2 测试 np 数据

一、使用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)

测试结果为:

标签:KNN,cv2,OpenCV,train,灰度,No.2,测试,np,数据
From: https://blog.csdn.net/qq_64603703/article/details/141268969

相关文章

  • 《机器学习》——运用OpenCV库中的KNN算法进行图像识别
    文章目录KNN算法的简单介绍下载OpenCV库实验内容实验结果完整代码自己手写数字传入模型中测试KNN算法的简单介绍一、KNN算法的基本要素K值的选择:K值代表选择与新测试样本距离最近的前K个训练样本数,通常K是不大于20的整数。K值的选择对算法结果有重要影响,需要通过交......
  • 《机器学习》 KNN算法、数据可视化 No.1
    一、了解机器学习1、什么是机器学习        机器学习是一种人工智能(AI)的分支,旨在让计算机通过数据自动学习和改进。机器学习算法被设计用于从数据中提取模式和规律,然后利用这些模式和规律来做出预测或做出决策,而无需明确的程序指令。        机器学习的基本......
  • java opencv 去噪+动态自适应二值化
    //连接opencvSystem.setProperty("java.awt.headless","false");System.out.println(System.getProperty("java.library.path"));URLurl=ClassLoader.getSystemResource("lib/opencv/opencv_java4100.dll");System.load(url.getPa......
  • java opencv 图像匹配识别
    //region图像匹配3.0privateMatimageMatch(Imageori,Imagetbi){System.setProperty("java.awt.headless","false");System.out.println(System.getProperty("java.library.path"));URLurl=ClassLoader.getSystem......
  • opencv
    一、读取视频读取视频文件与在OpenCV中读取图像文件非常相似,区别在于我们使用了cv2.videocapture。1.1读取视频需要用到的函数视频写入函数cv.VideoWriter()读取视频cv.VideoCapture.read()写入视频cv.VideoWriter.write(frame)打开,判断是否打开isOpene......
  • OpenCV/CV2,PIL,Tensor之间如何互相转化
    参考资料:torchvision文档众所周知OpenCV/CV2和PIL是Python领域最常使用的图像处理库,而PytorchTensor则是我们在深度学习领域接触最多的张量数据结构,知道这几种格式之间的相互转化方式是非常有必要的。三类,一共6种相互转化的链路,下面一一道来:1.OpenCV/CV2(ndar......
  • opencv关键点检测
    特征匹配主要是基于两种相似度较高的图片,通过opencv里面提供的特征匹配方法来进行特征点之间的匹配和映射特征点由关键点和描述子两部分组成。例如:在一张图像中计算SIFT特征点时,是指提取SIFT关键点,并计算SIFT描述子两件事。关键点是指特征点在图像里的位置,有些特征点还具有方向......
  • 【OpenCV教程】OpenCV中对矩阵的常用操作
    @目录1.全零矩阵2.全一矩阵3.单位矩阵4.矩阵转置5.求逆矩阵6.逗号式分隔创建矩阵7.矩阵定义(只列出常用的)7.1数据类型Scalar8.通过ptr与at函数遍历矩阵8.1Vec类型9.通过迭代器遍历矩阵(easybutveryveryslow)1.全零矩阵CV_NODISCARD_STDstaticMatExprMat::zeros(intr......
  • 【树莓派学习笔记2】opencv常用的视觉方案,特征颜色提取,模式匹配,图形映射函数
    本文主要介绍opencv里面一些常用的视觉方案,所需的全部代码均在如下1.给视觉单独开一个进程持续运行并更新全局变量#获取并处理图像defget_image():whileTrue:#开全局变量处理,分理处红绿蓝globalimage,image_red,image_green,image_blue......
  • opencv图像去雾
    1、何恺明的暗通道去雾算法     论文原文:SingleImageHazeRemovalUsingDarkChannelPrior|IEEEJournals&Magazine|IEEEXplore     参考博客:[论文阅读](11)ACE算法和暗通道先验图像去雾算法(Rizzi|何恺明老师)_暗通道去雾算法_Eastmount的博客......