• (3) OpenCV图像处理kNN近邻算法


    目录

    一、介绍

    1、类通过Matplotlib显示

    2、Matplotlib显示效果

    二、通过KNN近邻对新成员进行分类例程

    1、例程

    2、运行效果


    一、介绍

            这个想法是在特征空间中搜索测试数据的最近邻。我们将用下面的图片来研究它。

            在图像中,有两个族,蓝色(正方形)和红色(三角形)。我们称每一种为 “ ”。现在有一个新成员进入,显示为绿色(圆形)。他应该被添加到蓝色还是红色中,我们称该过程为 “ 分类 ” 。

            我们需要做的就是通过kNN近邻算法进行分类操作,因此让我们应用此算法。

            这种方法是检查谁是他的 最近邻(离的最近)。从图像中可以明显看出它是红色(三角形) 。因此,他也被添加到了红色(三角形) 中。此方法简称为 “ 最近邻 ”,因为分类仅取决于 “ 最近邻 ”。

            但这是有问题的。红色(三角形)可能是最近的。但是,如果附近有很多蓝色(正方形)怎么办?然后,蓝色(正方形)在该地区的权重比红色(三角形)更大。因此,仅检查最接近的 1 个是不够的。相反,我们检查 k 个 “ 近邻 ”,那么,谁占的多,新样本就属于那个 “ ” 。

            假如在我们的图像中,让我们取 k = 3 ,即检查 3 个 “ 近邻 ”。他有 1 个蓝色(正方形)和 2 个红色(三角形)(有两个等距的蓝色(正方形),但是由于 k = 3 ,我们只取其中一个),所以他又应该加入红色(三角形) 。但是,如果我们取 k = 7 怎么办?然后,他有 5 个蓝色(正方形)和 2 个红色(三角形),现在,他应该加入蓝色(正方形) 。因此,所有这些都随 k 的值而变化。更有趣的是,如果 k = 4 怎么办?他有 2 个蓝色(正方形) 和2个红色(三角形),这是一个平滑!因此最好将 k 作为奇数。由于分类取决于 k 个最近的 “ ”,因此该方法称为 “ k近邻 ” 。

            同样,在kNN中,我们确实在考虑 k 个近邻(离的最近),但我们对所有人都给予同等的重视,对吧?这公平吗?例如,以 k = 4 的情况为例。我们说这是平局。但是请注意,这1个红色(三角形)比其他2个蓝色(正方形)离他更近。因此,他更应该被添加到红色(三角形) 中。那么我们如何用数学解释呢?我们根据 “ ” 到新成员的距离来给他们一些权重。对于那些靠近他的 “ ” ,权重增加,而那些远离他的 “ ” ,权重减轻。然后,我们分别添加每个 “ ” 的总权重。谁得到的总权重最高,新成员归为那个 “ ” 。

            就像上面一样,我们将在这里做一个简单的例子,有两个 “ ” 。在这里,我们将红色系列标记为 “ Class_0 ”(0表示),将蓝色系列标记为 “ Class_1 ”(1表示)。我们创建 25 个随机数(随机坐标),并将它们标记为 “ 0 ” 或 “ 1 ” 。我们借助Numpy中的Random Number Generator来完成所有这些工作。然后我们在Matplotlib的帮助下对其进行绘制。红色系列显示为三角形,蓝色系列显示为正方形。

    1、类通过Matplotlib显示

    1. # 导入OpenCV库
    2. import cv2 as cv
    3. # 导入NumPy库,用于进行矩阵和数组的计算
    4. import numpy as np
    5. # 导入matplotlib的pyplot模块,用于数据的可视化
    6. import matplotlib.pyplot as plt
    7. # 使用NumPy的random.randint函数生成25个随机的二维向量,每个向量的元素值在0到100之间
    8. # 这些向量组成训练数据集,每个向量是一个样本,包含两个特征(x和y值)
    9. # astype(np.float32)将整数转换为浮点数,以便在计算时获得更高的精度
    10. trainData = np.random.randint(0,100,(25,2)).astype(np.float32)
    11. # 使用NumPy的random.randint函数生成25个随机的一维向量,每个向量的元素值在0到2之间,表示样本的标签(红色或蓝色)
    12. responses = np.random.randint(0,2,(25,1)).astype(np.float32)
    13. # 使用布尔索引从训练数据中选择标签为0(红色)的样本
    14. red = trainData[responses.ravel()==0]
    15. # 使用matplotlib的scatter函数绘制红色样本的散点图,参数80设定散点的大小,'r'设定散点的颜色,'^'设定散点的形状
    16. plt.scatter(red[:,0],red[:,1],80,'r','^')
    17. # 使用布尔索引从训练数据中选择标签为1(蓝色)的样本
    18. blue = trainData[responses.ravel()==1]
    19. # 使用matplotlib的scatter函数绘制蓝色样本的散点图,参数80设定散点的大小,'b'设定散点的颜色,'s'设定散点的形状
    20. plt.scatter(blue[:,0],blue[:,1],80,'b','s')
    21. # 使用matplotlib的show函数显示绘制的图像
    22. plt.show()

    2、Matplotlib显示效果

            

    二、通过KNN近邻对新成员进行分类例程

            我们将在OpenCV中的kNN的帮助下,将一个新成员带入,并将其进行 “ 分类 ”

    1、例程

    1. # 导入OpenCV库,并重命名为cv。OpenCV是一个开源的计算机视觉和机器学习软件库。
    2. import cv2 as cv
    3. # 导入NumPy库,并重命名为np。NumPy是一个用于大型多维数组和矩阵的数学运算的库,提供了数学函数来操作这些数组。
    4. import numpy as np
    5. # 导入matplotlib的pyplot模块,并重命名为plt。matplotlib是一个用于创建静态、动态、交互式和实时图表的Python库。
    6. import matplotlib.pyplot as plt
    7. # 使用NumPy的random.randint函数生成25个随机的二维向量,每个向量的元素值在0到100之间。
    8. # 这些向量组成训练数据集,每个向量是一个样本,包含两个特征(x和y值)。
    9. # astype(np.float32)将整数转换为浮点数,以便在计算时获得更高的精度。
    10. # 包含(x,y)值的25个已知/训练数据的特征集
    11. trainData = np.random.randint(0,100,(25,2)).astype(np.float32)
    12. # 使用NumPy的random.randint函数生成25个随机的一维向量,每个向量的元素值在0到2之间,表示样本的标签(红色或蓝色)。
    13. # 用数字0和1分别标记红色或蓝色
    14. responses = np.random.randint(0,2,(25,1)).astype(np.float32)
    15. # 使用布尔索引从训练数据中选择标签为0(红色)的样本
    16. red = trainData[responses.ravel()==0]
    17. # 使用matplotlib的scatter函数绘制红色样本的散点图,参数30设定散点的大小,'r'设定散点的颜色,'^'设定散点的形状。
    18. plt.scatter(red[:,0],red[:,1],30,'r','^')
    19. # 使用布尔索引从训练数据中选择标签为1(蓝色)的样本
    20. blue = trainData[responses.ravel()==1]
    21. # 使用matplotlib的scatter函数绘制蓝色样本的散点图,参数80设定散点的大小,'b'设定散点的颜色,'s'设定散点的形状。
    22. plt.scatter(blue[:,0],blue[:,1],80,'b','s')
    23. # 使用NumPy的random.randint函数生成1个随机的二维向量,每个向量的元素值在0到100之间。这个向量代表新的样本点。
    24. newcomer = np.random.randint(0,100,(1,2)).astype(np.float32)
    25. # 使用matplotlib的scatter函数绘制新样本点的散点图,参数80设定散点的大小,'g'设定散点的颜色,'o'设定散点的形状。
    26. plt.scatter(newcomer[:,0],newcomer[:,1],80,'g','o')
    27. # 使用OpenCV的ml.KNearest_create函数创建一个KNN分类器对象。KNN是一种监督学习算法,可以用于分类和回归。
    28. knn = cv.ml.KNearest_create()
    29. # 使用KNN分类器的train函数训练模型,输入参数为训练数据、样本类型(cv.ml.ROW_SAMPLE表示每行是一个样本)和训练数据的标签。
    30. knn.train(trainData, cv.ml.ROW_SAMPLE, responses)
    31. # 使用KNN分类器的findNearest函数进行预测,输入参数为新数据和k值(这里设置为3)。返回值为四个值:ret(返回状态,如果返回值为1表示预测成功)、results(预测结果)、neighbours(最近邻样本的索引)和dist(最近邻样本的距离)。
    32. ret, results, neighbours ,dist = knn.findNearest(newcomer, 3)
    33. # 打印预测结果。这是一个新样本的标签。
    34. print( "result: {}\n".format(results) )
    35. # 打印最近邻样本的索引。这是一个新样本的三个最近邻样本在训练数据集中的索引。
    36. print( "neighbours: {}\n".format(neighbours) )
    37. # 打印最近邻样本的距离。这是一个新样本与它的三个最近邻样本的距离。
    38. print( "distance: {}\n".format(dist) )
    39. # 使用matplotlib的show函数显示绘制的图像。
    40. plt.show()

    2、运行效果

            

            由上面的我们定义,将红色系列标记为 “ 0类 ” ,将蓝色系列标记为 “ 1类 ” ​​​​​​​。从下面的图片我们可以看出,新成员绿色(圆形),他有 2 个蓝色(正方形)和 1 个红色(三角形),所以他又应该加入蓝色(正方形) ​​​​​​​,也就是 “ 1类 ” 

  • 相关阅读:
    Linux学习笔记4 - 基础命令
    06-spring的beanFactoryPostProcessor的执行
    Scratch软件编程等级考试一级——20200913
    C++ STL 【stack&queue】模拟实现
    新四级冲刺需牢记的700核心词
    传奇外网架设常见的问题及解决办法-传奇创建人物失败/不开门/PAK显示密码错误/脚本错误
    计算机毕业设计Javaweb硕士研究生招生考试专业报考查询及学习系统设计与实现(源码+系统+mysql数据库+lw文档)
    软件项目管理判断题
    go net/http 源码解读
    [数据结构初阶]顺序表
  • 原文地址:https://blog.csdn.net/qq_26043945/article/details/133297686