赞
踩
pip install opencv-python
# 可以根据自己python的版本选择下载适配的opencv,可以在后面加上 == 指定版本
# 例如
pip install opencv-python==3.4.17.63
import cv2
- 1、获取数据
- 因为这次的实验已经给定了数据,所以只需要将这张图片存放在实验项目下,并读取到代码中即可
# 通过opencv中imread方法,读取图片
img = cv2.imread('digits.png')
2、处理数据
在完成一个实验项目过程中,获取数据和处理数据需要花费很多时间
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度图
# 将原始图像划分成独立的数字,每个数字大小20*20,共计5000个
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]
# 转换成array,形状(50,100,20,20),50行,100列,每个图像20*20大小
x = np.array(cells)
train = x[:, :50] # 划分训练集和测试集:比例各占一半
test = x[:, 50:100]
# 将数据构造为符合KNN的输入,将每个数字的尺寸由20*20调整为1*400(一行400个像素)
train_new = train.reshape(-1, 400).astype(np.float32) # Size = (2500,400)
test_new = test.reshape(-1, 400).astype(np.float32) # Size = (2500,400)
3、分配标签
分别为训练集数据、测试集数据分配标签(图像对应的实际值)
因为这里有10种数字,每类数字都需要重复分配标签250次
# 分配标签:分别为训练数据、测试数据分配标签(图像对应的实际值)
k = np.arange(10) # (0123456789)
labels = np.repeat(k, 250) # repeat->重复数组中的元素,每个元素重复250次
# np.newaxis是NumPy库中的一个特殊对象,用于在数组中增加一个新的维度
train_labels = labels[:, np.newaxis] # 在训练集种加入标签维度
test_labels = np.repeat(k, 250)[:, np.newaxis] # 生成一个测试标签,就是正确的结果,用于后面计算准确率
4、模型构建和训练
因为opencv库中有KNN算法,所以我们可以直接调用
在KNN算法中传入训练集和标签
# 模型构建+训练
knn = cv2.ml.KNearest_create() # 通过cv2创建一个KNN模型
# train训练方法
knn.train(train_new, cv2.ml.ROW_SAMPLE, train_labels) # cv2.ml.ROW_SAMPLE:这是一个标志,告诉OpenCV训练数据是按行组织的,即每一行代表一个样本,每一列代表一个特征
5、测试
# 测试
# findNearest测试方法
res, result, neighbours, dist = knn.findNearest(test_new, k=3)
# ret: 表示查找操作是否成功
# result:浮点数数组,表示测试样本的预测标签
# neighbours:这是一个整数数组,表示与测试样本最接近的K个邻居的索引。这些索引对应于训练集中的样本,可以用来检查哪些训练样本对预测结果产生了影响
# dist:这是一个浮点数组,表示测试样本与每个最近邻居之间的距离。这些距离可以帮助理解预测结果的置信度;距离越近,预测通常越可靠
6、通过测试集校验准确率
matches = result == test_labels
correct = np.count_nonzero(matches)
accuracy = correct * 100.0 / result.size
print("当前使用KNN识别手写数字的准确率为:", accuracy)
import numpy as np import cv2 img = cv2.imread('digits.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度图 # 将原始图像划分成独立的数字,每个数字大小20*20,共计5000个 cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)] # 转换成array,形状(50,100,20,20),50行,100列,每个图像20*20大小 x = np.array(cells) train = x[:, :50] # 划分训练集和测试集:比例各占一半 test = x[:, 50:100] # 将数据构造为符合KNN的输入,将每个数字的尺寸由20*20调整为1*400(一行400个像素) train_new = train.reshape(-1, 400).astype(np.float32) # Size = (2500,400) test_new = test.reshape(-1, 400).astype(np.float32) # Size = (2500,400) # 分配标签:分别为训练数据、测试数据分配标签(图像对应的实际值) k = np.arange(10) # (0123456789) labels = np.repeat(k, 250) # repeat重复数组中的元素,每个元素重复250次 train_labels = labels[:, np.newaxis] # np.newaxis是NumPy库中的一个特殊对象,用于在数组中增加一个新的维度 test_labels = np.repeat(k, 250)[:, np.newaxis] # 模型构建+训练 opencv里面也有KNN算法 knn = cv2.ml.KNearest_create() # 通过cv2创建一个KNN模型 knn.train(train_new, cv2.ml.ROW_SAMPLE, train_labels) # cv2.ml.ROW_SAMPLE:这是一个标志,告诉OpenCV训练数据是按行组织的,即每一行代表一个样本,每一列代表一个特征 # 测试 res, result, neighbours, dist = knn.findNearest(test_new, k=3) # ret: 表示查找操作是否成功 # result:浮点数数组,表示测试样本的预测标签 # neighbours:这是一个整数数组,表示与测试样本最接近的K个邻居的索引。这些索引对应于训练集中的样本,可以用来检查哪些训练样本对预测结果产生了影响 # dist:这是一个浮点数组,表示测试样本与每个最近邻居之间的距离。这些距离可以帮助理解预测结果的置信度;距离越近,预测通常越可靠 # 通过测试集校验准确率 matches = result == test_labels correct = np.count_nonzero(matches) accuracy = correct * 100.0 / result.size print("当前使用KNN识别手写数字的准确率为:", accuracy)
下图是通过电脑自带的画图工具,写出的数字6,并且已经将大小调整为20*20像素大小的图片
将图片经过与实验中相同的处理方法,加以处理并传入到模型中进行测试
# 读取图片
img_6 = cv2.imread('6.png')
# 将图片转换为灰度图
gray_6 = cv2.cvtColor(img_6, cv2.COLOR_BGR2GRAY)
# 将图片转换为数组结构
test_gray_6 = np.array(gray_6)
# 将尺寸由20*20调整为1*400(一行400个像素),才能符合KNN的输入结构
test_6 = test_gray_6.reshape(-1, 400).astype(np.float32)
# 将处理好的测试图片放入模型中
res_6, result_6, neighbours_6, dist_6 = knn.findNearest(test_6, k=3)
print(result_6)
得出结果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。