libsvm Minist Hog手書き認識(ソースファイル)
15690 ワード
以上は私の前の文章の中のコードの実現で、中はそれぞれopencvの中のSVMとLibSVMを使って、opencvのSVMは使うのがもっと便利で、しかし内部も実はLibsvmに基づいているようで、同じパラメータの訓練の結果は一致して、中にLibsvmの呼び出しの過程があって、もしlibsvmを使って工事の中でlibsvmのソースコードのファイルを追加する必要があるならばそれぞれsvmです.hとsvm.cpp、林智仁のライブラリに持参した2つのコアファイルでいいです.libsvmの使い方はCの書き方を使っているように感じられます.opencvでカプセル化された使いやすさがいいです.後でgithubにエンジニアリングファイルを置いてダウンロードします.何か間違いがあったら、批判してください.ここではMinistのデータセットを使っています.画像は私が処理した1枚の画像で、サイズは20*20で、中には詳しい関数の使用説明があります.
[https://github.com/YihangLou/SVM-Minist-HandWriting-Recognition]Githubのエンジニアリングリンク
[https://github.com/YihangLou/SVM-Minist-HandWriting-Recognition]Githubのエンジニアリングリンク
// DigitsRec_HOG_SVM.cpp : 。
#include "opencv2/opencv.hpp"
#include "fstream"
#include "svm.h"
using namespace std;
using namespace cv;
#define srcfeature
vector<string> trainImageList;// ,
vector<int> trainLabelList; //
vector<string> testImageList;// ,
string trainImageFile= "D:\\WorkSpace\\homework\\PatternRecognization\\ \\minist\\train_image\\imagelist.txt";
string testImageFile = "D:\\WorkSpace\\homework\\PatternRecognization\\ \\minist\\test_image\\imagelist.txt";
string testBasePath = "D:\\WorkSpace\\homework\\PatternRecognization\\ \\minist\\test_image\\";
string trainBasePath = "D:\\WorkSpace\\homework\\PatternRecognization\\ \\minist\\train_image\\";
string SVMModel ="svm_model.xml";
CvMat * dataMat;
CvMat * labelMat;
//***************************************************************
// : readTrainFileList
// :
// : public
// : void
// : string trainImageFile
// : string basePath
// : vector<string> & trainImageList list
// : vector<int> & trainLabelList list
//***************************************************************
void readTrainFileList(string trainImageFile, string basePath, vector<string> &trainImageList, vector<int> &trainLabelList)
{
ifstream readData( trainImageFile );
string buffer;
while( readData )
{
if( getline( readData, buffer))
{
int label = int((buffer[0])-'0');//
trainLabelList.push_back( label);
trainImageList.push_back( buffer );//
}
}
readData.close();
cout<<"Read Train Data Complete"<<endl;
}
//***************************************************************
// : readTestFileList
// :
// : public
// : void
// : string testImageFile
// : string basePath
// : vector<string> & testImageList
//***************************************************************
void readTestFileList(string testImageFile, string basePath, vector<string> &testImageList)
{
ifstream readData( testImageFile ); //
string buffer;
while( readData )
{
if( getline( readData, buffer))
{
testImageList.push_back( buffer );//
}
}
readData.close();
cout<<"Read Test Data Complete"<<endl;
}
//***************************************************************
// : processHogFeature
// : Hog
// : public
// : void
// : vector<string> trainImageList
// : vector<int> trainLabelList
// : CvMat * & dataMat
// : CvMat * & labelMat
//***************************************************************
void processHogFeature(vector<string> trainImageList,vector<int> trainLabelList, CvMat * &dataMat,CvMat * &labelMat)
{
int trainSampleNum = trainImageList.size();
dataMat = cvCreateMat( trainSampleNum, 324, CV_32FC1 ); //324 Hog feature Size
cvSetZero( dataMat );
labelMat = cvCreateMat( trainSampleNum, 1, CV_32FC1 );
cvSetZero( labelMat );
IplImage* src;
IplImage* trainImg=cvCreateImage(cvSize(20,20),8,3);//20 20
for( int i = 0; i != trainImageList.size(); i++ )
{
src=cvLoadImage( (trainBasePath + trainImageList[i]).c_str(),1);
if( src == NULL )
{
cout<<" can not load the image: "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
continue;
}
//cout<<"Calculate Hog Feature "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
cvResize(src,trainImg);
HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
vector<float>descriptors;
hog->compute(trainImg, descriptors,Size(1,1), Size(0,0));
int j =0;
for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
cvmSet(dataMat,i,j,*iter);// HOG
j++;
}
cvmSet( labelMat, i, 0, trainLabelList[i] );
//cout<<"Image and label "<<trainImageList[i].c_str()<<" "<<trainLabelList[i]<<endl;
}
cout<<"Calculate Hog Feature Complete"<<endl;
cout<<dataMat<<endl;
}
void processNonFeature(vector<string> trainImageList,vector<int> trainLabelList, CvMat * &dataMat,CvMat * &labelMat)
{
int trainSampleNum = trainImageList.size();
dataMat = cvCreateMat( trainSampleNum, 400, CV_32FC1 ); //324 Hog feature ,
cvSetZero( dataMat );
labelMat = cvCreateMat( trainSampleNum, 1, CV_32FC1 );
cvSetZero( labelMat );
IplImage* src;
IplImage* resizeImg=cvCreateImage(cvSize(20,20),8,3);//20 20
for( int i = 0; i != trainImageList.size(); i++ )
{
src=cvLoadImage( (trainBasePath + trainImageList[i]).c_str(),1);
if( src == NULL )
{
cout<<" can not load the image: "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
continue;
}
//cout<<"Calculate Hog Feature "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
cvResize(src,resizeImg);
IplImage * grayImage = cvCreateImage(cvGetSize(resizeImg), IPL_DEPTH_8U, 1);
cvCvtColor(resizeImg,grayImage,CV_BGR2GRAY);
//
IplImage * binaryImage = cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_8U,1);
cvThreshold(grayImage,binaryImage,25,255,CV_THRESH_BINARY);
//cvNamedWindow("src");
//cvShowImage("src", src);
//cvNamedWindow("show");
//cvShowImage("show", binaryImage);
//cvWaitKey(0);//
HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
vector<float>descriptors;
int j =0; //j , vector
uchar * tmp = new uchar;
for(int n=0;n<binaryImage->height;n++)
{ for(int m=0;m<binaryImage->width;m++)
{
*tmp=((uchar *)(binaryImage->imageData + n*binaryImage->widthStep))[m];
cvmSet(dataMat,i,j,*tmp);// HOG
j++;
}
}
cvmSet( labelMat, i, 0, trainLabelList[i] );
//cout<<"Image and label "<<trainImageList[i].c_str()<<" "<<trainLabelList[i]<<endl;
}
cout<<"Calculate Hog Feature Complete"<<endl;
}
//***************************************************************
// : trainSVM
// : opencv SVM
// : public
// : void
// : CvMat * & dataMat
// : CvMat * & labelMat
//***************************************************************
void trainSVM(CvMat * & dataMat,CvMat * & labelMat )
{
cout<<"train svm start"<<endl;
cout<<dataMat<<endl;
CvSVM svm;
CvSVMParams param;// SVM
CvTermCriteria criteria;
criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
svm.train( dataMat, labelMat, NULL, NULL, param );//
svm.save( SVMModel.c_str());
cout<<"SVM Training Complete"<<endl;
}
//***************************************************************
// : trainLibSVM
// : LibSVM SVM
// : public
// : void
// : CvMat * & dataMat
// : CvMat * & labelMat
//***************************************************************
void trainLibSVM(CvMat *& dataMat, CvMat * & labelMat)
{
cout<<"LibSVM start"<<endl;
// SVM
svm_parameter param;
//param.svm_type = C_SVC;
param.svm_type = EPSILON_SVR;
param.kernel_type = RBF;
param.degree = 10.0;
param.gamma = 0.09;
param.coef0 = 1.0;
param.nu = 0.5;
param.cache_size = 1000;
param.C = 10.0;
param.eps = 1e-3;
param.p = 1.0;
//svm_prob
svm_problem svm_prob;
int sampleNum = dataMat->rows;
int vectorLength = dataMat->cols;
svm_prob.l = sampleNum;
svm_prob.y = new double [sampleNum];
for (int i = 0; i < sampleNum; i++)
{
svm_prob.y[i] = cvmGet(labelMat,i,0);
}
cout<<"LibSVM middle"<<endl;
svm_prob.x = new svm_node * [sampleNum];
for (int i = 0; i < sampleNum; i++)
{
svm_node * x_space = new svm_node [vectorLength + 1];
for (int j = 0; j < vectorLength; j++)
{
x_space[j].index = j;
x_space[j].value = cvmGet(dataMat,i,j);
}
x_space[vectorLength].index = -1;// , ,
svm_prob.x[i] = x_space;
}
cout<<"LibSVM end"<<endl;
svm_model * svm_model = svm_train(&svm_prob, ¶m);
#ifdef srcfeature
svm_save_model("libsvm_minist_src_feature_model_.model",svm_model);
#else
svm_save_model("libsvm_minist_model.model",svm_model);
#endif
for (int i=0 ; i < sampleNum; i++)
{
delete [] svm_prob.x[i];
}
delete [] svm_prob.y;
svm_free_model_content(svm_model);
}
//***************************************************************
// : testSVM
// : opencv SVM
// : public
// : void
// : vector<string> testImageList
// : string SVMModel
//***************************************************************
void testSVM(vector<string> testImageList, string SVMModel)
{
CvSVM svm;
svm.load(SVMModel.c_str());//
IplImage* testImage;
IplImage* tempImage;
char buffer[512];
ofstream ResultOutput( "predict_result.txt" );//
for( int j = 0; j != testImageList.size(); j++ )//
{
testImage = cvLoadImage( (testBasePath+testImageList[j]).c_str(), 1);
if( testImage == NULL )
{
cout<<" can not load the image: "<<(testBasePath+testImageList[j]).c_str()<<endl;
continue;
}
tempImage =cvCreateImage(cvSize(20,20),8,3);
cvZero(tempImage);
cvResize(testImage,tempImage);
HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
vector<float>descriptors;
hog->compute(tempImage, descriptors,Size(1,1), Size(0,0));
CvMat* TempMat=cvCreateMat(1,descriptors.size(),CV_32FC1);
int n=0;
for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
cvmSet(TempMat,0,n,*iter);
n++;
}
int resultLabel = svm.predict(TempMat);//
sprintf( buffer, "%s %d\r
",testImageList[j].c_str(),resultLabel );
ResultOutput<<buffer;
}
cvReleaseImage(&testImage);
cvReleaseImage(&tempImage);
ResultOutput.close();
cout<<"SVM Predict Complete"<<endl;
}
//***************************************************************
// : testLibSVM
// : LisbSVM
// : public
// : void
// : string LibSVMModelFile
// : vector<string> testImageList
// : string SVMModel
//***************************************************************
void testLibSVM(string LibSVMModelFile, vector<string> testImageList, string SVMModel)
{
svm_model * svm = svm_load_model(LibSVMModelFile.c_str());
IplImage* testImage;
IplImage* tempImage;
char buffer[512];
ofstream ResultOutput( "libsvm_predict_result.txt" );
for( int j = 0; j != testImageList.size(); j++ )//
{
testImage = cvLoadImage( (testBasePath+testImageList[j]).c_str(), 1);
if( testImage == NULL )
{
cout<<" can not load the image: "<<(testBasePath+testImageList[j]).c_str()<<endl;
continue;
}
tempImage =cvCreateImage(cvSize(20,20),8,3);
cvZero(tempImage);
cvResize(testImage,tempImage);
HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
vector<float>descriptors;
hog->compute(tempImage, descriptors,Size(1,1), Size(0,0));
svm_node * inputVector = new svm_node [ descriptors.size()+1];
int n = 0;
for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
inputVector[n].index = n;
inputVector[n].value = *iter;
n++;
}
inputVector[n].index = -1;
int resultLabel = svm_predict(svm,inputVector);//
sprintf( buffer, "%s %d\r
",testImageList[j].c_str(),resultLabel );
ResultOutput<<buffer;
delete [] inputVector;
}
svm_free_model_content(svm);
cvReleaseImage(&testImage);
cvReleaseImage(&tempImage);
ResultOutput.close();
cout<<"SVM Predict Complete"<<endl;
}
//***************************************************************
// : releaseAll
// :
// : public
// : void
//***************************************************************
void releaseAll()
{
cvReleaseMat( &dataMat );
cvReleaseMat( &labelMat);
cout<<"Release All Complete"<<endl;
}
//***************************************************************
// : main
// : SVM, opencv , libsvm , svm
// : public
// : int
//***************************************************************
int main()
{
readTrainFileList(trainImageFile,trainBasePath,trainImageList,trainLabelList);
processHogFeature(trainImageList,trainLabelList, dataMat,labelMat);
//trainSVM(dataMat,labelMat );
//processNonFeature(trainImageList,trainLabelList, dataMat,labelMat);
trainLibSVM(dataMat,labelMat);
//readTestFileList( testImageFile, testBasePath, testImageList);
testLibSVM("libsvm_minist_model.model",testImageList,SVMModel);
//testSVM( testImageList, SVMModel);
releaseAll();
return 0;
}