SVM手写字符识别小程序
来源:互联网 发布:c语言的预处理命令 编辑:程序博客网 时间:2024/04/29 23:48
该程序是基于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,1sampleFeatureMat.setTo( 0 ); // 850,64cout << "开始读取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_EPSILONcv::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 );}
最后的结果输出类似如下:
0 0
- SVM手写字符识别小程序
- SVM手写字符识别
- SVM - 手写数字识别
- SVM手写数字识别
- opencv(三):HOG+SVM实现手写字符识别
- arm9板子上写了一个小程序:手写数字及英文大小写字符的识别
- SVM用于手写数字识别
- pca+svm手写数字识别
- 基于SVM手写数字识别
- 手写数字识别hebb和SVM
- SVM和Knn实现手写数字识别
- SVM手写数字的识别---python
- 手写svm识别人是否戴眼镜
- 【机器学习 sklearn】手写数字识别 SVM
- OpenCV OpenGL手写字符识别
- 车牌识别-字符识别(HOG+SVM)
- 手写数字识别(二)----SVM 实现Mnist-image 手写数字图像识别
- 利用Hog 特征进行手写字符识别
- Lesson 18: SDK文档:Tutorial 7 Texture Mapping and Constant Buffers分析
- 还原启动U盘
- Junit单元测试
- Proxy Server代理服务器
- 一道BFS加区间题的教训
- SVM手写字符识别小程序
- ajax返回的数据 用easyui的datagrid的表格来循环显示,用灰色背景的是隐藏的列。点击可以获取到隐藏的值
- pip(包管理器)
- MP4文件数据格式
- Mybatis的使用
- 播放gif图片
- killall的一些用法
- chrome浏览器处理本地Ajax跨域
- echo print() print_r() var_dump()的区别