SVM手写字符识别小程序
2016-12-17 10:54
232 查看
该程序是基于opencv3.1写的,自己的训练样本图片,图片大小都是32X32,主要思路是利用灰度图在行和列方向上的投影得到的64(32+32)个标签进行数据分类
主函数如下:
对应的头文件:
具体的函数实现:
最后的结果输出类似如下:
主函数如下:
#include"LetterDet.h" int main() { image_read(); image_SVMClassify(); cv::waitKey(); return 0; }
对应的头文件:
/*********************************************************** *为什么变成 D:\testImages\ 就会出错 *转义序列 \" 表示双引号,而不是字符串的结尾 *http://blog.csdn.net/holybin/article/details/17751063 **********************************************************/ #ifndef LETTERDET_H #define LETTERDET_H #include<opencv2\opencv.hpp> #include<iostream> #include<string.h> #include<stdlib.h> #include<sstream> #include<fstream> using namespace std; #define source_path "D:\testImages" #define feature_path "features.txt" //cv::Mat FeatureMat = cv::Mat::zeros( 860 , 64 , CV_32FC1 ); //cv::Mat LabelMat = cv::Mat::zeros( 1 , 860 , CV_32SC1 ); void image_read(); void image_feature_write( cv::Mat& image , int label ); void getTrainingDataAndLabel(); void image_SVMClassify(); #endif
具体的函数实现:
#include"LetterDet.h" cv::Mat sampleFeatureMat = cv::Mat::zeros( 850 , 64 , CV_32FC1 ); // SVM训练数据是行向量 cv::Mat sampleLabelMat = cv::Mat::zeros( 850 , 1 , CV_32SC1 ); // SVM标签是列向量 void image_read() { for( int i = 0; i < 10; i++ ) { for( int j = 0; j < 85; j++ ) { stringstream str; // 读取一系列图片 str << "D:\\testImages\\" << i << "_" << j << ".jpg"; cv::Mat srcImage = cv::imread( str.str() , 0 ); if( !srcImage.data ) { cout << "读取失败,请检查该图片是否存在!!!" << endl; exit( 0 ); } else { // cout << str.str() << "\t读取成功!" << endl; } image_feature_write( srcImage , i ); } } } void image_feature_write( cv::Mat& image , int label ) { FILE* file; if( fopen_s( &file , feature_path , "a+" ) ) // 以可附加的方式打开只写文件,若文件不存在则建立 { cout << "Can't open file!" << endl; exit( 0 ); } else { // getFeature(); for( int i = 0; i < image.rows; i++ ) //投影到X轴的所有像素和 { int sum = 0; uchar* ptr = image.ptr( i ); for( int j = 0; j < image.cols; j++ ) { sum += ptr[j]; } fprintf( file , " %d" , sum ); } for( int j = 0; j < image.cols; j++ ) //投影到Y轴的所有像素和 { int sum = 0; for( int i = 0; i < image.rows; i++ ) { sum += image.at<uchar>( i , j ); } fprintf( file , " %d" , sum ); } } fprintf( file , " %d" , label ); fprintf( file , "\n" ); fclose( file ); // 一定要记得关闭文件 } void getTrainingDataAndLabel() { FILE* file; // if( fopen_s( &file , feature_path , "a+" ) ) file=fopen( feature_path , "r" ); /*if( fopen_s( &file , feature_path , "r" ) ) { cout << "打开features.txt文件成功!" << endl; } else { cout << "打开features.txt文件失败!" << endl; }*/ // ifstream fr; // 记得包含库文件<fstream> // fr.open( feature_path , ios::in ); sampleLabelMat.setTo( 0 ); // 850,1 sampleFeatureMat.setTo( 0 ); // 850,64 cout << "开始读取features.txt文件中的数据" << endl; for( int i = 0; i < 850; i++ ) { for( int j = 0; j < 65; j++ ) { if( j == 64 ) { fscanf( file , "%d" , &sampleLabelMat.at<int>( i , 0 ) ); continue; } else { fscanf( file , "%f" , &sampleFeatureMat.at<float>( i , j ) ); } } } fclose( file ); } void image_SVMClassify() { getTrainingDataAndLabel(); cout << "开始训练Auto分类器..." << endl; cv::Ptr<cv::ml::SVM> m_SVM = cv::ml::SVM::create(); m_SVM->setType( cv::ml::SVM::C_SVC ); // SVM类型为C_SVM,可以进行2类以上的分类 m_SVM->setKernel( cv::ml::SVM::LINEAR ); // 核函数径向基函数,线性的不可分没法用 m_SVM->setC( 0.01 ); // 应该是松弛因子的惩罚系数C ? m_SVM->setTermCriteria( cv::TermCriteria( CV_TERMCRIT_ITER + CV_TERMCRIT_EPS , 1000 , FLT_EPSILON ) );//设定终止条件为迭代1000次或者误差小于FLT_EPSILON cv::Ptr<cv::ml::TrainData> trainDataSet = cv::ml::TrainData::create( sampleFeatureMat , cv::ml::ROW_SAMPLE , sampleLabelMat ); m_SVM->trainAuto( trainDataSet , 10 , cv::ml::SVM::getDefaultGrid( cv::ml::SVM::C ) , cv::ml::SVM::getDefaultGrid( cv::ml::SVM::GAMMA ) , cv::ml::SVM::getDefaultGrid( cv::ml::SVM::P ) , cv::ml::SVM::getDefaultGrid( cv::ml::SVM::NU ) , cv::ml::SVM::getDefaultGrid( cv::ml::SVM::COEF ) , cv::ml::SVM::getDefaultGrid( cv::ml::SVM::DEGREE ) , true ); // m_SVM->train( sampleFeatureMat , cv::ml::SampleTypes::ROW_SAMPLE , sampleLabelMat ); cv::Mat image = cv::imread( "8_90.jpg" , 0 ); // cv::imshow( "Image" , image ); cv::Mat test( 1 , 64 , CV_32FC1 ); for( int i = 0; i < image.rows; i++ ) //投影到X轴的所有像素和 { int sum = 0; uchar* ptr = image.ptr( i ); for( int j = 0; j < image.cols; j++ ) { sum += ptr[j]; } test.at<float>( 0 , i ) = sum; } for( int j = 0; j < image.cols; j++ ) //投影到Y轴的所有像素和 { int sum = 0; for( int i = 0; i < image.rows; i++ ) { sum += image.at<uchar>( i , j ); } test.at<float>( 0 , image.rows + j ) = sum; } int response = ( int ) m_SVM->predict( test ); printf( "response:%d\n" , response ); }
最后的结果输出类似如下:
相关文章推荐
- 我的第一个svm程序:手写字识别
- opencv(三):HOG+SVM实现手写字符识别
- arm9板子上写了一个小程序:手写数字及英文大小写字符的识别
- SVM手写字符识别
- opencv 基于KNN的手写数字字符识别
- python 实现识别手写 MNIST数字集的程序
- 基于Opencv库中SVM模块的MNIST手写字识别数据库识别
- 神经网络实现手写字符识别系统
- Opencv Python版学习笔记(八)字符识别-分类器(SVM,KNearest,RTrees,Boost,MLP)
- SVM 手写数字识别
- SVM对手写数字的识别
- 利用SVM(支持向量机)和MNIST库在OpenCV环境下实现手写数字0~9的识别
- BP神经网络应用于手写数字识别--matlab程序
- OpenCV OpenGL手写字符识别
- 手写数字识别hebb和SVM
- HOG+SVM行人识别程序运行时出现异常
- 基于opencv的手写数字识别(MFC,HOG,SVM)
- 车牌识别技术详解五--采用LBP+HOG SVM做目标分类,车牌检测,字符检测等
- OpenCV手写数字字符识别(基于k近邻算法)
- OpenCV OpenGL手写字符识别