学习OpenCV——SVM 手写数字检测
转自http://blog.csdn.net/firefight/article/details/6452188
是MNIST手写数字图片库:http://code.google.com/p/supplement-of-the-mnist-database-of-handwritten-digits/downloads/list
其他方法:http://blog.csdn.net/onezeros/article/details/5672192
使用OPENCV训练手写数字识别分类器
1,下载训练数据和测试数据文件,这里用的是MNIST手写数字图片库,其中训练数据库中为60000个,测试数据库中为10000个
2,创建训练数据和测试数据文件读取函数,注意字节顺序为大端
3,确定字符特征方式为最简单的8×8网格内的字符点数
4,创建SVM,训练并读取,结果如下
1000个训练样本,测试数据正确率80.21%(并没有体现SVM小样本高准确率的特性啊)
10000个训练样本,测试数据正确率95.45%
60000个训练样本,测试数据正确率97.67%
5,编写手写输入的GUI程序,并进行验证,效果还可以接受。
以下为主要代码,以供参考
(类似的也实现了随机树分类器,比较发现在相同的样本数情况下,SVM准确率略高)
- #include "stdafx.h"
- #include <fstream>
- #include "opencv2/opencv.hpp"
- #include <vector>
- using namespace std;
- using namespace cv;
- #define SHOW_PROCESS 0
- #define ON_STUDY 0
- class NumTrainData
- {
- public:
- NumTrainData()
- {
- memset(data, 0, sizeof(data));
- result = -1;
- }
- public:
- float data[64];
- int result;
- };
- vector<NumTrainData> buffer;
- int featureLen = 64;
- void swapBuffer(char* buf)
- {
- char temp;
- temp = *(buf);
- *buf = *(buf+3);
- *(buf+3) = temp;
- temp = *(buf+1);
- *(buf+1) = *(buf+2);
- *(buf+2) = temp;
- }
- void GetROI(Mat& src, Mat& dst)
- {
- int left, right, top, bottom;
- left = src.cols;
- right = 0;
- top = src.rows;
- bottom = 0;
- //Get valid area
- for(int i=0; i<src.rows; i++)
- {
- for(int j=0; j<src.cols; j++)
- {
- if(src.at<uchar>(i, j) > 0)
- {
- if(j<left) left = j;
- if(j>right) right = j;
- if(i<top) top = i;
- if(i>bottom) bottom = i;
- }
- }
- }
- //Point center;
- //center.x = (left + right) / 2;
- //center.y = (top + bottom) / 2;
- int width = right - left;
- int height = bottom - top;
- int len = (width < height) ? height : width;
- //Create a squre
- dst = Mat::zeros(len, len, CV_8UC1);
- //Copy valid data to squre center
- Rect dstRect((len - width)/2, (len - height)/2, width, height);
- Rect srcRect(left, top, width, height);
- Mat dstROI = dst(dstRect);
- Mat srcROI = src(srcRect);
- srcROI.copyTo(dstROI);
- }
- int ReadTrainData(int maxCount)
- {
- //Open image and label file
- const char fileName[] = "../res/train-images.idx3-ubyte";
- const char labelFileName[] = "../res/train-labels.idx1-ubyte";
- ifstream lab_ifs(labelFileName, ios_base::binary);
- ifstream ifs(fileName, ios_base::binary);
- if( ifs.fail() == true )
- return -1;
- if( lab_ifs.fail() == true )
- return -1;
- //Read train data number and image rows / cols
- char magicNum[4], ccount[4], crows[4], ccols[4];
- ifs.read(magicNum, sizeof(magicNum));
- ifs.read(ccount, sizeof(ccount));
- ifs.read(crows, sizeof(crows));
- ifs.read(ccols, sizeof(ccols));
- int count, rows, cols;
- swapBuffer(ccount);
- swapBuffer(crows);
- swapBuffer(ccols);
- memcpy(&count, ccount, sizeof(count));
- memcpy(&rows, crows, sizeof(rows));
- memcpy(&cols, ccols, sizeof(cols));
- //Just skip label header
- lab_ifs.read(magicNum, sizeof(magicNum));
- lab_ifs.read(ccount, sizeof(ccount));
- //Create source and show image matrix
- Mat src = Mat::zeros(rows, cols, CV_8UC1);
- Mat temp = Mat::zeros(8, 8, CV_8UC1);
- Mat img, dst;
- char label = 0;
- Scalar templateColor(255, 0, 255 );
- NumTrainData rtd;
- //int loop = 1000;
- int total = 0;
- while(!ifs.eof())
- {
- if(total >= count)
- break;
- total++;
- cout << total << endl;
- //Read label
- lab_ifs.read(&label, 1);
- label = label + '0';
- //Read source data
- ifs.read((char*)src.data, rows * cols);
- GetROI(src, dst);
- #if(SHOW_PROCESS)
- //Too small to watch
- img = Mat::zeros(dst.rows*10, dst.cols*10, CV_8UC1);
- resize(dst, img, img.size());
- stringstream ss;
- ss << "Number " << label;
- string text = ss.str();
- putText(img, text, Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.0, templateColor);
- //imshow("img", img);
- #endif
- rtd.result = label;
- resize(dst, temp, temp.size());
- //threshold(temp, temp, 10, 1, CV_THRESH_BINARY);
- for(int i = 0; i<8; i++)
- {
- for(int j = 0; j<8; j++)
- {
- rtd.data[ i*8 + j] = temp.at<uchar>(i, j);
- }
- }
- buffer.push_back(rtd);
- //if(waitKey(0)==27) //ESC to quit
- // break;
- maxCount--;
- if(maxCount == 0)
- break;
- }
- ifs.close();
- lab_ifs.close();
- return 0;
- }
- void newRtStudy(vector<NumTrainData>& trainData)
- {
- int testCount = trainData.size();
- Mat data = Mat::zeros(testCount, featureLen, CV_32FC1);
- Mat res = Mat::zeros(testCount, 1, CV_32SC1);
- for (int i= 0; i< testCount; i++)
- {
- NumTrainData td = trainData.at(i);
- memcpy(data.data + i*featureLen*sizeof(float), td.data, featureLen*sizeof(float));
- res.at<unsigned int>(i, 0) = td.result;
- }
- /START RT TRAINNING//
- CvRTrees forest;
- CvMat* var_importance = 0;
- forest.train( data, CV_ROW_SAMPLE, res, Mat(), Mat(), Mat(), Mat(),
- CvRTParams(10,10,0,false,15,0,true,4,100,0.01f,CV_TERMCRIT_ITER));
- forest.save( "new_rtrees.xml" );
- }
- int newRtPredict()
- {
- CvRTrees forest;
- forest.load( "new_rtrees.xml" );
- const char fileName[] = "../res/t10k-images.idx3-ubyte";
- const char labelFileName[] = "../res/t10k-labels.idx1-ubyte";
- ifstream lab_ifs(labelFileName, ios_base::binary);
- ifstream ifs(fileName, ios_base::binary);
- if( ifs.fail() == true )
- return -1;
- if( lab_ifs.fail() == true )
- return -1;
- char magicNum[4], ccount[4], crows[4], ccols[4];
- ifs.read(magicNum, sizeof(magicNum));
- ifs.read(ccount, sizeof(ccount));
- ifs.read(crows, sizeof(crows));
- ifs.read(ccols, sizeof(ccols));
- int count, rows, cols;
- swapBuffer(ccount);
- swapBuffer(crows);
- swapBuffer(ccols);
- memcpy(&count, ccount, sizeof(count));
- memcpy(&rows, crows, sizeof(rows));
- memcpy(&cols, ccols, sizeof(cols));
- Mat src = Mat::zeros(rows, cols, CV_8UC1);
- Mat temp = Mat::zeros(8, 8, CV_8UC1);
- Mat m = Mat::zeros(1, featureLen, CV_32FC1);
- Mat img, dst;
- //Just skip label header
- lab_ifs.read(magicNum, sizeof(magicNum));
- lab_ifs.read(ccount, sizeof(ccount));
- char label = 0;
- Scalar templateColor(255, 0, 0);
- NumTrainData rtd;
- int right = 0, error = 0, total = 0;
- int right_1 = 0, error_1 = 0, right_2 = 0, error_2 = 0;
- while(ifs.good())
- {
- //Read label
- lab_ifs.read(&label, 1);
- label = label + '0';
- //Read data
- ifs.read((char*)src.data, rows * cols);
- GetROI(src, dst);
- //Too small to watch
- img = Mat::zeros(dst.rows*30, dst.cols*30, CV_8UC3);
- resize(dst, img, img.size());
- rtd.result = label;
- resize(dst, temp, temp.size());
- //threshold(temp, temp, 10, 1, CV_THRESH_BINARY);
- for(int i = 0; i<8; i++)
- {
- for(int j = 0; j<8; j++)
- {
- m.at<float>(0,j + i*8) = temp.at<uchar>(i, j);
- }
- }
- if(total >= count)
- break;
- char ret = (char)forest.predict(m);
- if(ret == label)
- {
- right++;
- if(total <= 5000)
- right_1++;
- else
- right_2++;
- }
- else
- {
- error++;
- if(total <= 5000)
- error_1++;
- else
- error_2++;
- }
- total++;
- #if(SHOW_PROCESS)
- stringstream ss;
- ss << "Number " << label << ", predict " << ret;
- string text = ss.str();
- putText(img, text, Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.0, templateColor);
- imshow("img", img);
- if(waitKey(0)==27) //ESC to quit
- break;
- #endif
- }
- ifs.close();
- lab_ifs.close();
- stringstream ss;
- ss << "Total " << total << ", right " << right <<", error " << error;
- string text = ss.str();
- putText(img, text, Point(50, 50), FONT_HERSHEY_SIMPLEX, 1.0, templateColor);
- imshow("img", img);
- waitKey(0);
- return 0;
- }
- void newSvmStudy(vector<NumTrainData>& trainData)
- {
- int testCount = trainData.size();
- Mat m = Mat::zeros(1, featureLen, CV_32FC1);
- Mat data = Mat::zeros(testCount, featureLen, CV_32FC1);
- Mat res = Mat::zeros(testCount, 1, CV_32SC1);
- for (int i= 0; i< testCount; i++)
- {
- NumTrainData td = trainData.at(i);
- memcpy(m.data, td.data, featureLen*sizeof(float));
- normalize(m, m);
- memcpy(data.data + i*featureLen*sizeof(float), m.data, featureLen*sizeof(float));
- res.at<unsigned int>(i, 0) = td.result;
- }
- /START SVM TRAINNING//
- CvSVM svm = CvSVM();
- CvSVMParams param;
- CvTermCriteria criteria;
- criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
- param= CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);
- svm.train(data, res, Mat(), Mat(), param);
- svm.save( "SVM_DATA.xml" );
- }
- int newSvmPredict()
- {
- CvSVM svm = CvSVM();
- svm.load( "SVM_DATA.xml" );
- const char fileName[] = "../res/t10k-images.idx3-ubyte";
- const char labelFileName[] = "../res/t10k-labels.idx1-ubyte";
- ifstream lab_ifs(labelFileName, ios_base::binary);
- ifstream ifs(fileName, ios_base::binary);
- if( ifs.fail() == true )
- return -1;
- if( lab_ifs.fail() == true )
- return -1;
- char magicNum[4], ccount[4], crows[4], ccols[4];
- ifs.read(magicNum, sizeof(magicNum));
- ifs.read(ccount, sizeof(ccount));
- ifs.read(crows, sizeof(crows));
- ifs.read(ccols, sizeof(ccols));
- int count, rows, cols;
- swapBuffer(ccount);
- swapBuffer(crows);
- swapBuffer(ccols);
- memcpy(&count, ccount, sizeof(count));
- memcpy(&rows, crows, sizeof(rows));
- memcpy(&cols, ccols, sizeof(cols));
- Mat src = Mat::zeros(rows, cols, CV_8UC1);
- Mat temp = Mat::zeros(8, 8, CV_8UC1);
- Mat m = Mat::zeros(1, featureLen, CV_32FC1);
- Mat img, dst;
- //Just skip label header
- lab_ifs.read(magicNum, sizeof(magicNum));
- lab_ifs.read(ccount, sizeof(ccount));
- char label = 0;
- Scalar templateColor(255, 0, 0);
- NumTrainData rtd;
- int right = 0, error = 0, total = 0;
- int right_1 = 0, error_1 = 0, right_2 = 0, error_2 = 0;
- while(ifs.good())
- {
- //Read label
- lab_ifs.read(&label, 1);
- label = label + '0';
- //Read data
- ifs.read((char*)src.data, rows * cols);
- GetROI(src, dst);
- //Too small to watch
- img = Mat::zeros(dst.rows*30, dst.cols*30, CV_8UC3);
- resize(dst, img, img.size());
- rtd.result = label;
- resize(dst, temp, temp.size());
- //threshold(temp, temp, 10, 1, CV_THRESH_BINARY);
- for(int i = 0; i<8; i++)
- {
- for(int j = 0; j<8; j++)
- {
- m.at<float>(0,j + i*8) = temp.at<uchar>(i, j);
- }
- }
- if(total >= count)
- break;
- normalize(m, m);
- char ret = (char)svm.predict(m);
- if(ret == label)
- {
- right++;
- if(total <= 5000)
- right_1++;
- else
- right_2++;
- }
- else
- {
- error++;
- if(total <= 5000)
- error_1++;
- else
- error_2++;
- }
- total++;
- #if(SHOW_PROCESS)
- stringstream ss;
- ss << "Number " << label << ", predict " << ret;
- string text = ss.str();
- putText(img, text, Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.0, templateColor);
- imshow("img", img);
- if(waitKey(0)==27) //ESC to quit
- break;
- #endif
- }
- ifs.close();
- lab_ifs.close();
- stringstream ss;
- ss << "Total " << total << ", right " << right <<", error " << error;
- string text = ss.str();
- putText(img, text, Point(50, 50), FONT_HERSHEY_SIMPLEX, 1.0, templateColor);
- imshow("img", img);
- waitKey(0);
- return 0;
- }
- int main( int argc, char *argv[] )
- {
- #if(ON_STUDY)
- int maxCount = 60000;
- ReadTrainData(maxCount);
- //newRtStudy(buffer);
- newSvmStudy(buffer);
- #else
- //newRtPredict();
- newSvmPredict();
- #endif
- return 0;
- }
- //from: http://blog.csdn.net/yangtrees/article/details/7458466
学习OpenCV——SVM 手写数字检测相关推荐
- python手写数字识别教学_python实现基于SVM手写数字识别功能
本文实例为大家分享了SVM手写数字识别功能的具体代码,供大家参考,具体内容如下 1.SVM手写数字识别 识别步骤: (1)样本图像的准备. (2)图像尺寸标准化:将图像大小都标准化为8*8大小. (3 ...
- 【学习日记】手写数字识别及神经网络基本模型
2021.10.7 [学习日记]手写数字识别及神经网络基本模型 1 概述 张量(tensor)是数字的容器,是矩阵向任意维度的推广,其维度称为轴(axis).深度学习的本质是对张量做各种运算处理,其分 ...
- 书接上文,基于藏文手写数字数据开发构建yolov5n轻量级藏文手写数字检测识别系统
在上一篇文章中: <python基于轻量级CNN模型开发构建手写藏文数字识别系统> 开发实现了轻量级的藏文手写数字识别系统,这里主要是想基于前文的数据,整合目标检测模型来进一步挖掘藏文手写 ...
- 深度学习数字仪表盘识别_【深度学习系列】手写数字识别实战
上周在搜索关于深度学习分布式运行方式的资料时,无意间搜到了paddlepaddle,发现这个框架的分布式训练方案做的还挺不错的,想跟大家分享一下.不过呢,这块内容太复杂了,所以就简单的介绍一下padd ...
- 深度学习项目实战——手写数字识别项目
摘要 本文将介绍的有关于的paddle的实战的相关的问题,并分析相关的代码的阅读和解释.并扩展有关于的python的有关的语言.介绍了深度学习步骤: 1. 数据处理:读取数据 和 预处理操作 2. 模 ...
- CNN学习MNIST实现手写数字识别
CNN的实现 我们之前已经实现了卷积层和池化层,现在来组合这些层,搭建进行手写数字识别的CNN. # 初始化权重 self.params = {'W1': weight_init_std * np.r ...
- 深度学习入门实践学习——手写数字识别(百度飞桨平台)——上篇
一.项目平台 百度飞桨 二.项目框架 1.数据处理: 2.模型设计:网络结构,损失函数: 3.训练配置:优化器,资源配置: 4.训练过程: 5.保存加载. 三.手写数字识别任务 1.构建神经网络流程: ...
- 【第一个深度学习模型应用-手写数字识别】
基于BP神经网络的手写数字识别报告 基于BP神经网络的手写数字识别报告 一.任务描述 二.数据集来源 三.方法 3.1 数据集处理方法 3.2.模型结构设计 3.3.模型算法 四.实验 4.1.实验环 ...
- svm手写数字识别_KNN 算法实战篇如何识别手写数字
上篇文章介绍了KNN 算法的原理,今天来介绍如何使用KNN 算法识别手写数字? 1,手写数字数据集 手写数字数据集是一个用于图像处理的数据集,这些数据描绘了 [0, 9] 的数字,我们可以用KNN 算 ...
- 基于opencv的手写数字字符识别
摘要 本程序主要参照论文,<基于OpenCV的脱机手写字符识别技术>实现了,对于手写阿拉伯数字的识别工作.识别工作分为三大步骤:预处理,特征提取,分类识别.预处理过程主要找到图像的ROI部 ...
最新文章
- 轻松获取LAMP,LNMP环境编译参数配置
- Tomcat 源码阅读记录(1)
- solidworks入门
- c#语言编写汉诺塔游戏,c#实现汉诺塔问题示例
- pads最新版本是多少_电路EDA软件究竟有多少?
- Xshell5 提示要继续使用此程序,您必须应用最新的更新或使用新版本
- .NET 6新特性试用 | TryGetNonEnumeratedCount
- C# -- 多线程向同一文件写入
- C#4.0 命名参数可选参数
- hrbp 牵着鼻子走_防止被下属牵着鼻子走的四个经典方法,学会了,下属就好管了...
- 怎么关闭vivo系统自检_手机系统越来越卡,把握这几个优化设置,让手机流畅起来...
- Microsoft Office 2010 中的 Office 检测到此文件有问题
- github 从0开始的基本操作到fork和pr项目
- 信号完整性分析的基础概念
- redis主从配置及主从切换
- 应用场景:征信和权属管理
- 怎么在MAC系统下查看系统详细信息?新手快来看!
- 2 pygraphviz在windows10 64位下的安装问题(反斜杠的血案)
- 【开源】java做游戏之QQ连连看java单机高仿版(算是目前最高仿的了)
- 驱动开发:运用VAD隐藏R3内存思路