在opencv3中实现机器学习算法之:利用最近邻算法(knn)实现手写数字分类
手写数字digits分类,这可是深度学习算法的入门练习。而且还有专门的手写数字MINIST库。opencv提供了一张手写数字图片给我们,先来看看

这是一张密密麻麻的手写数字图:图片大小为1000*2000,有0-9的10个数字,每5行为一个数字,总共50行,共有5000个手写数字。在opencv3.0版本中,图片存放位置为
/opencv/sources/samples/data/digits.png
我们首先要做的,就是把这5000个手写数字,一个个截取出来,每个数字块大小为20*20。直接将每个小图块进行序列化,因此最终得到一个5000*400的特征矩阵。样本数为5000,维度为400维。取其中前3000个样本进行训练。
注意:截取的时候,是按列截取。不然取前3000个样本进行训练就会出现后几个数字训练不到。
具体代码:
#include "stdafx.h"
#include "opencv2\opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::ml; int main()
{
Mat img = imread("E:/opencv/opencv/sources/samples/data/digits.png");
Mat gray;
cvtColor(img, gray, CV_BGR2GRAY);
int b = ;
int m = gray.rows / b; //原图为1000*2000
int n = gray.cols / b; //裁剪为5000个20*20的小图块
Mat data,labels; //特征矩阵
for (int i = ; i < n; i++)
{
int offsetCol = i*b; //列上的偏移量
for (int j = ; j < m; j++)
{
int offsetRow = j*b; //行上的偏移量
//截取20*20的小块
Mat tmp;
gray(Range(offsetRow, offsetRow + b), Range(offsetCol, offsetCol + b)).copyTo(tmp);
data.push_back(tmp.reshape(,)); //序列化后放入特征矩阵
labels.push_back((int)j / ); //对应的标注
} }
data.convertTo(data, CV_32F); //uchar型转换为cv_32f
int samplesNum = data.rows;
int trainNum = ;
Mat trainData, trainLabels;
trainData = data(Range(, trainNum), Range::all()); //前3000个样本为训练数据
trainLabels = labels(Range(, trainNum), Range::all()); //使用KNN算法
int K = ;
Ptr<TrainData> tData = TrainData::create(trainData, ROW_SAMPLE, trainLabels);
Ptr<KNearest> model = KNearest::create();
model->setDefaultK(K);
model->setIsClassifier(true);
model->train(tData); //预测分类
double train_hr = , test_hr = ;
Mat response;
// compute prediction error on train and test data
for (int i = ; i < samplesNum; i++)
{
Mat sample = data.row(i);
float r = model->predict(sample); //对所有行进行预测
//预测结果与原结果相比,相等为1,不等为0
r = std::abs(r - labels.at<int>(i)) <= FLT_EPSILON ? .f : .f; if (i < trainNum)
train_hr += r; //累积正确数
else
test_hr += r;
} test_hr /= samplesNum - trainNum;
train_hr = trainNum > ? train_hr / trainNum : .; printf("accuracy: train = %.1f%%, test = %.1f%%\n",
train_hr*., test_hr*.);
waitKey();
return ;
}
根据经验,利用最近邻算法对手写数字进行分类,会有很高的精度,因此在本文中我们采用的是knn算法。
最终结果:

训练精度为95.9%, 测试精度为92.6%。如果对手写数字识别准确率达不到90%以上,就没有什么实际作用了。如果调整训练样本数,这个精度应该会有所改变。
在opencv3中实现机器学习算法之:利用最近邻算法(knn)实现手写数字分类的更多相关文章
- 在opencv3中实现机器学习之:利用逻辑斯谛回归(logistic regression)分类
logistic regression,注意这个单词logistic ,并不是逻辑(logic)的意思,音译过来应该是逻辑斯谛回归,或者直接叫logistic回归,并不是什么逻辑回归.大部分人都叫成逻 ...
- 吴裕雄--天生自然python机器学习实战:K-NN算法约会网站好友喜好预测以及手写数字预测分类实验
实验设备与软件环境 硬件环境:内存ddr3 4G及以上的x86架构主机一部 系统环境:windows 软件环境:Anaconda2(64位),python3.5,jupyter 内核版本:window ...
- TensorFlow.NET机器学习入门【5】采用神经网络实现手写数字识别(MNIST)
从这篇文章开始,终于要干点正儿八经的工作了,前面都是准备工作.这次我们要解决机器学习的经典问题,MNIST手写数字识别. 首先介绍一下数据集.请首先解压:TF_Net\Asset\mnist_png. ...
- 在opencv3中实现机器学习之:利用svm(支持向量机)分类
svm分类算法在opencv3中有了很大的变动,取消了CvSVMParams这个类,因此在参数设定上会有些改变. opencv中的svm分类代码,来源于libsvm. #include "s ...
- 在opencv3中实现机器学习之:利用正态贝叶斯分类
opencv3.0版本中,实现正态贝叶斯分类器(Normal Bayes Classifier)分类实例 #include "stdafx.h" #include "op ...
- 在opencv3中的机器学习算法
在opencv3.0中,提供了一个ml.cpp的文件,这里面全是机器学习的算法,共提供了这么几种: 1.正态贝叶斯:normal Bayessian classifier 我已在另外一篇博文中介 ...
- 机器学习(二)-kNN手写数字识别
一.kNN算法是机器学习的入门算法,其中不涉及训练,主要思想是计算待测点和参照点的距离,选取距离较近的参照点的类别作为待测点的的类别. 1,距离可以是欧式距离,夹角余弦距离等等. 2,k值不能选择太大 ...
- 手写数字识别的k-近邻算法实现
(本文为原创,请勿在未经允许的情况下转载) 前言 手写字符识别是机器学习的入门问题,k-近邻算法(kNN算法)是机器学习的入门算法.本文将介绍k-近邻算法的原理.手写字符识别问题分析.手写字符识别的k ...
- TensorFlow下利用MNIST训练模型识别手写数字
本文将参考TensorFlow中文社区官方文档使用mnist数据集训练一个多层卷积神经网络(LeNet5网络),并利用所训练的模型识别自己手写数字. 训练MNIST数据集,并保存训练模型 # Pyth ...
随机推荐
- Android性能优化(一)
Android性能优化典范 1.大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能. 从设计师的角度,他们希望App能够有更多的动画,图片等时尚元素来实现流畅的用户体验. 但是Android ...
- 我们需要专职的QA吗?
[ 引用评论里的一句话:hurt but true 抛开作者某些偏激的想法外,作者暴露出来的问题还是需要测试思考的: 1.TestCase,TestData,TestConfiguration 没有 ...
- Windows 编 程中的字符串
(1)在win32编程中,如何使用string类型 #include <string> using namespace std; LPTSTR lpCmdLine = L" ...
- js 毫秒 转 时间 日期 yyyy-mm-dd hh-mm-ss
//格式化时间 var format = function(time, format){ var t = new Date(time); var tf = function(i){return (i ...
- SPC.NET,为5年的开发做个结尾
从08年到如今从事asp.net开发已五年,起初只是一个简单的喜好,想做个东西出来.于是SPC.NET的前生诞生了,直至今日. 不得不说,一个人开发一个软件是很辛苦的事情,以下是SPC.NET的一些特 ...
- mongo学习笔记(五):分片
分片 人脸: 代表客户端,客户端肯定说,你数据库分片不分片跟我没关系,我叫你干啥就干啥,没什么好商量的. mongos: 首先我们要了解”片键“的概念,也就是说拆分集合的依据是什么?按照 ...
- linux下RTNETLINK answers: File exists的解决方案
重启网卡时 出现 :RTNETLINK answers: File exists 提示 以下是网卡出来错误的解决方法: 第一种: 和 NetworkManager 服务有冲突,这个好解决,直接关闭 ...
- Android开发之 Windows环境下通过Eclipse创建的第一个安卓应用程序(图文详细步骤)
第一篇 windows环境下搭建创建的第一个安卓应用程序 为了方便,我这里只采用了一体包进行演示. 一.下载安卓环境的一体包. 官网下载:安卓官网(一般被墙了) 网盘下载: http://yunpa ...
- webstorm 注册码
User Name: EMBRACE License Key: ===== LICENSE BEGIN ===== 24718-12042010 00001h6wzKLpfo3gmjJ8xoTPw5m ...
- Tip和菜单的实现方式
Tip和菜单有类似的功能,即鼠标光标移上去的时候显示指定元素,鼠标光标离开的时候隐藏该元素.如下 示例1:下拉菜单(鼠标移动到“客户服务”上时出现,离开则隐藏) 示例2:水平菜单(鼠标移动到“餐饮美食 ...