一、K近邻

有两个类,红色、蓝色。我将红色点标记为0,蓝色点标记为1。还要创建25个训练数据,把它们分别标记为0或者1。Numpy中随机数产生器可以帮助我们完成这个任务

  1. import cv2
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4.  
  5. # 包含25个已知/训练数据的(x,y)值的特征集
  6. trainData = np.random.randint(, , (, )).astype(np.float32)
  7.  
  8. # 用数字0和1分别标记红色和蓝色
  9. responses = np.random.randint(, , (, )).astype(np.float32)
  10.  
  11. # 画出红色的点
  12. red = trainData[responses.ravel() == ]
  13. plt.scatter(red[:, ], red[:, ], , 'r', '^')
  14.  
  15. # 画出蓝色的点
  16. blue = trainData[responses.ravel() == ]
  17. plt.scatter(blue[:, ], blue[:, ], , 'b', 's')
  18.  
  19. plt.show()

很有可能你运行的图和我的不一样,因为使用了随机数产生器,每次运行代码都会得到不同的结果。

下面就是KNN算法分类器的初始化,我们要传入一个训练数据集,以及对应的label。我们给它一个测试数据,让它来进行分类。OpenCV中使用knn.findNearest()函数

  参数1:测试数据

  参数2:k的值

  返回值1:由kNN算法计算得到的测试数据的类别标志(0 或 1)。如果你想使用最近邻算法,只需要将k设置1,k就是最近邻的数目

  返回值2:k的最近邻居的类别标志

  返回值3:每个最近邻居到测试数据的距离

测试数据被标记为绿色。

  1. # newcomer为测试数据
  2. newcomer = np.random.randint(, , (, )).astype(np.float32)
  3. plt.scatter(newcomer[:,],newcomer[:,],,'g','o')
  4.  
  5. knn = cv2.ml.KNearest_create()
  6. knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
  7. ret, results, neighbours, dist = knn.findNearest(newcomer, )
  8.  
  9. print("result: ", results, "\n")
  10. print("neighbours: ", neighbours,"\n")
  11. print("distance: ", dist)
  12.  
  13. plt.scatter(red[:, ], red[:, ], , 'r', '^')
  14. plt.scatter(blue[:, ], blue[:, ], , 'b', 's')
  15.  
  16. plt.show()

下面是我得到的结果:

  1. result: [[.]]
  2.  
  3. neighbours: [[. . .]]
  4.  
  5. distance: [[. . .]]

测试数据有三个邻居,有两个是红色,一个是蓝色。因此测试数据被分为红色。

二、使用kNN对手写数字OCR

OCR(Optical Character Recognition,光学字符识别

目标

  1. 要根据我们掌握的kNN知识创建一个基本的OCR程序

  2. 使用OpenCV自带的手写数字和字母数据测试我们的程序

手写数字的OCR

我们的目的是创建一个可以对手写数字进行识别的程序。需要训练数据和测试数据。OpenCV 安装包中有一副图片(/samples/python2/data/digits.png),其中有一幅有5000个手写数字(每个数字重复500遍)。每个数字是一个20x20的小图。所以第一步就是将这个图像分割成5000个不同的数字,将拆分后的每一个数字图像展成400个像素点的图像(1x400的一维向量)。这个就是我们的特征集,所有像素的灰度值。我们使用每个数字的前250个样本做训练数据,剩余的250个做测试数据。

  1. import numpy as np
  2. import cv2
  3. import matplotlib.pyplot as plt
  4.  
  5. img = cv2.imread('digits.png')
  6. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  7.  
  8. # 我们把图片分成5000张,每张20 x
  9. cells = [np.hsplit(row, ) for row in np.vsplit(gray, )]
  10.  
  11. # 使cells变成一个numpy数组,它的维度为(, , , )
  12. x = np.array(cells)
  13.  
  14. # 训练数据和测试数据
  15. train = x[:, :].reshape(-, ).astype(np.float32) # size = (, )
  16. test = x[:, :].reshape(-, ).astype(np.float32) # size = (, )
  17.  
  18. # 为训练集和测试集创建一个label
  19. k = np.arange()
  20. train_labels = np.repeat(k, )[:, np.newaxis]
  21. test_labels = train_labels.copy()
  22.  
  23. # 初始化KNN,训练数据、测试KNN,k=
  24. knn = cv2.ml.KNearest_create()
  25. knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
  26. ret, result, neighbours, dist = knn.findNearest(test, k=)
  27.  
  28. # 分类的准确率
  29. # 比较结果和test_labels
  30. matches = result==test_labels
  31. correct = np.count_nonzero(matches)
  32. accuracy = correct * 100.0 / result.size
  33. print(accuracy)

结果为:

  1. 91.76

为了避免每次运行程序都要准备和训练分类器,我们最好把它保留,这样在下次运行时,只需要从文件中读取这些数据开始进行分类就可以了。

  1. # 保留数据
  2. np.savez('knn_data.npz', train=train, train_labels=train_labels)
  3.  
  4. # 加载数据
  5. with np.load('knn_data.npz') as data:
  6. print(data.files)
  7. train = data['train']
  8. train_labels = data['train_labels']

结果为:

  1. ['train', 'train_labels']

英文字母的OCR

接下来我们来做英文字母的OCR。和上面做法一样,但是数据和特征集有一些不同。OpenCV自带的数据文件(/samples/cpp/letter-recognition.data)。有20000行,每一行的第一列是我们的一个字母标记,接下来的16个数字是它的不同特征。取前10000个作为训练样本,剩下的10000个作为测试样本。我们先把字母表换成ascII,因为我们不直接处理字母。

  1. data = np.loadtxt('letter-recognition.data', dtype='float32', delimiter=',', converters={:lambda ch:ord(ch) - ord('A')})
  2.  
  3. # 将数据分成2份,10000个训练,10000个测试
  4. train, test = np.vsplit(data, )
  5.  
  6. # 将训练集和测试集分解为数据、label
  7. # 实际上每一行的第一列是我们的一个字母标记。接下来的 个数字是它的不同特征。
  8. responses, trainData = np.hsplit(train, []) # 数据从第二列开始
  9. labels, testData = np.hsplit(test, [])
  10.  
  11. # 初始化KNN,训练数据、测试KNN,k=
  12. knn = cv2.ml.KNearest_create()
  13. knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
  14. ret, result, neighbours, dist = knn.findNearest(testData, k=)
  15.  
  16. # 分类的准确率
  17. # 比较结果和test_labels
  18. correct = np.count_nonzero(result==labels)
  19. accuracy = correct * 100.0 / result.size
  20. print(accuracy)

结果为:

  1. 93.06
  1.  

  

OpenCV中的KNN的更多相关文章

  1. [OpenCV-Python] OpenCV 中机器学习 部分 VIII

    部分 VIII机器学习 OpenCV-Python 中文教程(搬运)目录 46 K 近邻(k-Nearest Neighbour ) 46.1 理解 K 近邻目标 • 本节我们要理解 k 近邻(kNN ...

  2. Opencv中KNN背景分割器

    背景分割器BackgroundSubtractor是专门用来视频分析的,会对视频中的每一帧进行"学习",比较,计算阴影,排除检测图像的阴影区域,按照时间推移的方法提高运动分析的结果 ...

  3. opencv中Mat与IplImage,CVMat类型之间转换

    opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...

  4. 解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。

    说明:本文所有算法的涉及到的优化均指在PC上进行的,对于其他构架是否合适未知,请自行试验. Box Filter,最经典的一种领域操作,在无数的场合中都有着广泛的应用,作为一个很基础的函数,其性能的好 ...

  5. OpenCV中IplImage图像格式与BYTE图像数据的转换

    最近在将Karlsruhe Institute of Technology的Andreas Geiger发表在ACCV2010上的Efficent Large-Scale Stereo Matchin ...

  6. opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较

    opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较 参考: http://wenku.baidu.com/link?url=1aDYAJBCrrK-uk2w3sSNai7h52x_ ...

  7. 混合高斯模型:opencv中MOG2的代码结构梳理

    /* 头文件:OurGaussmix2.h */ #include "opencv2/core/core.hpp" #include <list> #include&q ...

  8. opencv中的.at方法

    opencv中的.at方法是用来获取图像像素值得函数: interpolation:差值 histogram:直方图

  9. 【OpenCV】OpenCV中GPU模块使用

    CUDA基本使用方法 在介绍OpenCV中GPU模块使用之前,先回顾下CUDA的一般使用方法,其基本步骤如下: 1.主机代码执行:2.传输数据到GPU:3.确定grid,block大小: 4.调用内核 ...

随机推荐

  1. 【CSA72G】【XSY3316】rectangle 线段树 最小生成树

    题目大意 有一个 \(n\times n\) 的矩阵 \(A\).最开始 \(A\) 中每个元素的值都为 \(0\). 有 \(m\) 次操作,每次给你 \(x_1,x_2,y_1,y_2,w\),对 ...

  2. Educational Codeforces Round 63 (Rated for Div. 2)

    传送门 A. Reverse a Substring 题意: 给你一串 s,让你判断能否通过反转区间[l,r]的元素,使得反转后的串的字典序小于 s: 如果能,输出 "YES",并 ...

  3. 2018-2019-2 网络对抗技术 20165232 Exp3 免杀原理与实践

    2018-2019-2 网络对抗技术 20165232 Exp3 免杀原理与实践 免杀原理及基础问题回答 一.免杀原理 一般是对恶意软件做处理,让它不被杀毒软件所检测.也是渗透测试中需要使用到的技术. ...

  4. JAVA中循环删除list中元素的方法总结【转】

    印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...

  5. [源码分析]StringBuffer

    [源码分析]StringBuffer StringBuffer是继承自AbstractStringBuilder的. 这里附上另外两篇文章的连接: AbstractStringBuilder : ht ...

  6. Linux 文本处理工具记录

    Shuffle lines of multi files 现在有 1000 个文本文件(0.txt ~ 999.txt),每个文件大概 11M,总共 11G,我想把这 1000 个文本文件的内容随机组 ...

  7. Base64 加密解密

    /// <summary> /// 编码 Base64 /// </summary> /// <param name="code"></p ...

  8. IDEA配置github并上传项目

    https://www.cnblogs.com/jinjiyese153/p/6796668.html

  9. PLSQL Developer导入dmp文件,一闪而过

    在导入数据的时候,一闪而过,也没有任何报错信息. 在环境变量里添加ORACLE_HOME=D:\app\product\11.2.0\dbhome_1就行,此路径是指oracle安装路径.我是用这种方 ...

  10. 【转】Java中的新生代、老年代、永久代和各种GC

    JVM中的堆,一般分为三大部分:新生代.老年代.永久代: 1 新生代 主要是用来存放新生的对象.一般占据堆的1/3空间.由于频繁创建对象,所以新生代会频繁触发MinorGC进行垃圾回收. 新生代又分为 ...