一、K近邻

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

import cv2
import numpy as np
import matplotlib.pyplot as plt # 包含25个已知/训练数据的(x,y)值的特征集
trainData = np.random.randint(, , (, )).astype(np.float32) # 用数字0和1分别标记红色和蓝色
responses = np.random.randint(, , (, )).astype(np.float32) # 画出红色的点
red = trainData[responses.ravel() == ]
plt.scatter(red[:, ], red[:, ], , 'r', '^') # 画出蓝色的点
blue = trainData[responses.ravel() == ]
plt.scatter(blue[:, ], blue[:, ], , 'b', 's') plt.show()

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

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

  参数1:测试数据

  参数2:k的值

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

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

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

测试数据被标记为绿色。

# newcomer为测试数据
newcomer = np.random.randint(, , (, )).astype(np.float32)
plt.scatter(newcomer[:,],newcomer[:,],,'g','o') knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
ret, results, neighbours, dist = knn.findNearest(newcomer, ) print("result: ", results, "\n")
print("neighbours: ", neighbours,"\n")
print("distance: ", dist) plt.scatter(red[:, ], red[:, ], , 'r', '^')
plt.scatter(blue[:, ], blue[:, ], , 'b', 's') plt.show()

下面是我得到的结果:

result:  [[.]] 

neighbours:  [[. . .]] 

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个做测试数据。

import numpy as np
import cv2
import matplotlib.pyplot as plt img = cv2.imread('digits.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 我们把图片分成5000张,每张20 x
cells = [np.hsplit(row, ) for row in np.vsplit(gray, )] # 使cells变成一个numpy数组,它的维度为(, , , )
x = np.array(cells) # 训练数据和测试数据
train = x[:, :].reshape(-, ).astype(np.float32) # size = (, )
test = x[:, :].reshape(-, ).astype(np.float32) # size = (, ) # 为训练集和测试集创建一个label
k = np.arange()
train_labels = np.repeat(k, )[:, np.newaxis]
test_labels = train_labels.copy() # 初始化KNN,训练数据、测试KNN,k=
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
ret, result, neighbours, dist = knn.findNearest(test, k=) # 分类的准确率
# 比较结果和test_labels
matches = result==test_labels
correct = np.count_nonzero(matches)
accuracy = correct * 100.0 / result.size
print(accuracy)

结果为:

91.76

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

# 保留数据
np.savez('knn_data.npz', train=train, train_labels=train_labels) # 加载数据
with np.load('knn_data.npz') as data:
print(data.files)
train = data['train']
train_labels = data['train_labels']

结果为:

['train', 'train_labels']

英文字母的OCR

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

data = np.loadtxt('letter-recognition.data', dtype='float32', delimiter=',', converters={:lambda ch:ord(ch) - ord('A')})

# 将数据分成2份,10000个训练,10000个测试
train, test = np.vsplit(data, ) # 将训练集和测试集分解为数据、label
# 实际上每一行的第一列是我们的一个字母标记。接下来的 个数字是它的不同特征。
responses, trainData = np.hsplit(train, []) # 数据从第二列开始
labels, testData = np.hsplit(test, []) # 初始化KNN,训练数据、测试KNN,k=
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
ret, result, neighbours, dist = knn.findNearest(testData, k=) # 分类的准确率
# 比较结果和test_labels
correct = np.count_nonzero(result==labels)
accuracy = correct * 100.0 / result.size
print(accuracy)

结果为:

93.06

  

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. [LOJ3084][GXOI/GZOI2019]宝牌一大堆——DP

    题目链接: [GXOI/GZOI2019]宝牌一大堆 求最大值容易想到$DP$,但如果将$7$种和牌都考虑进来的话,$DP$状态不好设,我们将比较特殊的七小对和国士无双单独求,其他的进行$DP$. 观 ...

  2. Tenka1 Programmer Contest 2019

    C:即要使前一部分为白色后一部分为黑色,枚举分割点前缀和计算答案取min即可. #include<bits/stdc++.h> using namespace std; #define l ...

  3. BZOJ5507 GXOI/GZOI2019旧词 (树链剖分+线段树)

    https://www.cnblogs.com/Gloid/p/9412357.html差分一下是一样的问题.感觉几年没写过树剖了. #include<iostream> #include ...

  4. 堆以及一些用法 QWQ这是写得最认真的板子题

    最近一直在学图论,然后吧,由于学的东西实在是太多太杂了,加上蒟蒻本蒻又经常颓,所以落了好多好多板子题的整理没写啊嘤嘤嘤,不过把这些东西学的差不多了,再一块写个整理,其实感觉还不错?????也算是很神奇 ...

  5. 牛客小白月赛13 小A买彩票 (记忆化搜索)

    链接:https://ac.nowcoder.com/acm/contest/549/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...

  6. bzoj1997 Planar

    题目链接 思路 首先以那个环为框架,把所有的边连出来.如果有两条边相交,那么就把其中一条放到环外面去. 如图: \((1,3)\)与\((2,5)相交,\)(1,4)\(与\)(2,5)相交.所以我们 ...

  7. CF235B Let's Play Osu! 期望DP

    貌似是一道很裸的期望\(DP\).直接说思路: 设\(f[i]\)表示到\(i\)位置时的期望分数,但是只有\(f[i]\)的话我们发现是无法转移的,我们还需要知道到\(i\)位置时的期望连续长度,于 ...

  8. SaltStack 介绍和安装

    SaltStack 介绍和安装 SaltStack 介绍 SaltStack是一种利用Python语言开发的,用于批量管理主机的一套工具,主要实现三种功能: 远程执行:通过saltstack工具,可以 ...

  9. java ,用公司框架写的显示列表 Table控件

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" lan ...

  10. ASP.NET之页面传值

    一.目前在ASP.NET中页面传值共有这么几种方式: 1.使用QueryString变量QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中.如果是传递一个或多个安全 ...