OpenCV中,可以直接调用自带的模块函数。不需要再手动编写复杂的K邻近过程。本节介绍如何通过K邻近算法来确定一个坐标属于哪一组。本节介绍KNN的基本使用方法。

本文目录:

问题描述

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

两组训练的数据集分布情况示意

问题分析

创建两组数据,每组包含20对随机数,一组X和Y的坐标值都在(0,30)范围内,另一组X和Y的坐标值都在(70,100)范围内。

将第一组随机数划分为类型0,标签为0;另一组随机数划分为类型1,标签为1。

再随机生成一个在(0,100)的随机数对。

最后使用K邻近模块判断生成的随机数是属于类型0还是类型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))

#数据标签,共两类:0和1
#r1Label对应着rand1的标签,为类型0
r1Label = np.zeros((20,1)).astype(np.float32)
#r2Label对应着rand2的标签,为类型1
r2Label = np.ones((20,1)).astype(np.float32)
tdLabel = np.vstack((r1Label,r2Label))

#使用绿色标注类型0
g = trainData[tdLabel.ravel()==0]  #多维展平函数
plt.scatter(g[:,0],g[:,1],80,'g','o')
#使用蓝色标注类型1
b = trainData[tdLabel.ravel()==1]  #多维展平函数
plt.scatter(b[:,0],b[:,1],80,'b','s')

# plt.show()

#生成一个随机数,该数值在0到100之间
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
knn.train(trainData,cv2.ml.ROW_SAMPLE,tdLabel)
#使用K邻近算法分类
ret,result,neighbours,dist = knn.findNearest(test,5)

#显示当前结果
print("随机数的坐标是:",test)
print('随机数判定的结果:',result)
print("距离当前最近的5个邻居点:",neighbours)
print("5个最近的邻居距离:",dist)

plt.show()

随机数的坐标是: [[10. 78.]]
随机数判定的结果: [[0.]]
距离当前最近的5个邻居点: [[0. 0. 0. 0. 0.]]
5个最近的邻居距离: [[2402. 2426. 2501. 2501. 2536.]]

运行结果

知识补充:

1、np.vstack():按垂直方向(行顺序)堆叠数组构成一个新的数组,堆叠的数组需要具有相同的维度

函数演示示意

2、ravel()多维数据展平函数

>>> a = np.array([[1,2,3],[4,5,6]])

>>> a

​ array([[1, 2, 3], [4, 5, 6]])

>>> a.ravel()

​ array([1, 2, 3, 4, 5, 6])


博主个人公众号
版权声明 ▶ 本网站名称:陶小桃Blog
▶ 本文链接:https://www.52txr.cn/2022/CVKNN2.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!

最后修改:2022 年 05 月 25 日
如果觉得我的文章对你有用,请随意赞赏