基于qt和opencv3实现机器学习之:利用最近邻算法(knn)实现手写数字分类
来源:互联网 发布:海报素材网站知乎 编辑:程序博客网 时间:2024/06/15 22:09
手写数字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 = 20; int m = gray.rows / b; //原图为1000*2000 int n = gray.cols / b; //裁剪为5000个20*20的小图块 Mat data,labels; //特征矩阵 for (int i = 0; i < n; i++) { int offsetCol = i*b; //列上的偏移量 for (int j = 0; 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(0,1)); //序列化后放入特征矩阵 labels.push_back((int)j / 5); //对应的标注 } } data.convertTo(data, CV_32F); //uchar型转换为cv_32f int samplesNum = data.rows; int trainNum = 3000; Mat trainData, trainLabels; trainData = data(Range(0, trainNum), Range::all()); //前3000个样本为训练数据 trainLabels = labels(Range(0, trainNum), Range::all()); //使用KNN算法 int K = 5; 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 = 0, test_hr = 0; Mat response; // compute prediction error on train and test data for (int i = 0; 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 ? 1.f : 0.f; if (i < trainNum) train_hr += r; //累积正确数 else test_hr += r; } test_hr /= samplesNum - trainNum; train_hr = trainNum > 0 ? train_hr / trainNum : 1.; printf("accuracy: train = %.1f%%, test = %.1f%%\n", train_hr*100., test_hr*100.); waitKey(0); return 0;}
根据经验,利用最近邻算法对手写数字进行分类,会有很高的精度,因此在本文中我们采用的是knn算法。
最终结果
0 0
- 基于qt和opencv3实现机器学习之:利用最近邻算法(knn)实现手写数字分类
- 在OpenCV3中实现机器学习算法之:利用最近邻算法(knn)实现手写数字分类
- 基于qt和opencv3实现机器学习之:利用svm(支持向量机)分类
- 基于qt和opencv3实现机器学习之:利用正态贝叶斯分类
- 基于qt和opencv3实现机器学习之:利用逻辑斯谛回归(logistic regression)分类
- 机器学习之K-最近邻规则分类(KNN)算法
- 【机器学习】Knn算法实现手写数字识别
- 基于qt和opencv3实现机器学习之:对OCR进行分类
- 机器学习实战k近邻算法(kNN)应用之手写数字识别代码解读
- 【机器学习算法实现】kNN算法__手写识别——基于Python和NumPy函数库
- 【机器学习算法实现】kNN算法__手写识别——基于Python和NumPy函数库
- 【机器学习算法实现】kNN算法__手写识别——基于Python和NumPy函数库
- 【机器学习算法实现】kNN算法__手写识别——基于Python和NumPy函数库
- 基于qt和opencv3实现机器学习之:kmeans
- knn-2 利用knn算法实现手写数字识别
- 02--机器学习之最近邻规则分类(KNN)
- 【机器学习】KNN k近邻分类算法
- 【机器学习】k-近邻算法应用之手写数字识别
- 人生几何,对酒当歌
- 【搜索】洛谷 P1002 过河卒
- bzoj 1005: [HNOI2008]明明的烦恼 组合数学 + purfer序列
- 使用ltp编译出来的cws_cmdline,cp到其他机器上执行报错:/lib64/libc.so.6: version `GLIBC_2.14′ not found
- Vue-cli使用指南
- 基于qt和opencv3实现机器学习之:利用最近邻算法(knn)实现手写数字分类
- Java多线程方面的编程笔试题(通过继承Thread类启动线程)
- 从零开始学Snaker(二)- 工作流操作
- 图的深度优先与广度优先搜索
- cron表达式详解
- windows10系统下Java环境搭建
- 利用jTessBoxEditor工具进行Tesseract3.02.02样本训练,提高验证码识别率
- 原生JS写Ajax的请求函数
- 信号的基本知识