參考:https://blog.csdn.net/chaipp0607/article/details/68067098
//--------------------------------------【程式說明】-------------------------------------------
//
//------------------------------------------------------------------------------------------------
//---------------------------------【標頭檔案、名稱空間包含部分】----------------------------
// 描述:包含程式所使用的標頭檔案和名稱空間
//------------------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
#include <io.h>
#include <iostream>
using namespace cv;
using namespace std;
#if 0 /***資料準備*****/
int main()
{
char ad[128]={0};
int filename = 0,filenum=0;
Mat img = imread("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的小圖塊
for (int i = 0; i < m; i++)
{
int offsetRow = i*b; //行上的偏移量
if(i%5==0&&i!=0)
{
filename++;
filenum=0;
}
for (int j = 0; j < n; j++)
{
int offsetCol = j*b; //列上的偏移量
sprintf_s(ad, "F:\\data\\%d\\%d.jpg",filename,filenum++);
printf("start ad = %s \n" , ad);
//擷取20*20的小塊
Mat tmp;
gray(Range(offsetRow, offsetRow + b), Range(offsetCol, offsetCol + b)).copyTo(tmp);
// imshow(ad,tmp);
imwrite(ad,tmp);
}
}
waitKey(0);
destroyAllWindows();
return 0;
}
#elif 0
void getFiles( string path, vector<string>& files);
void get_0(Mat& trainingImages, vector<int>& trainingLabels);
void get_1(Mat& trainingImages, vector<int>& trainingLabels);
void get_2(Mat& trainingImages, vector<int>& trainingLabels);
/****模型訓練****/
int main()
{
//獲取訓練資料
Mat classes;
Mat trainingData;
Mat trainingImages;
vector<int> trainingLabels;
get_2(trainingImages, trainingLabels);
get_1(trainingImages, trainingLabels);
get_0(trainingImages, trainingLabels);
Mat(trainingImages).copyTo(trainingData);
trainingData.convertTo(trainingData, CV_32FC1);
Mat(trainingLabels).copyTo(classes);
//配置SVM訓練器引數
CvSVMParams SVM_params;
SVM_params.svm_type = CvSVM::C_SVC;
SVM_params.kernel_type = CvSVM::LINEAR;
SVM_params.degree = 0;
SVM_params.gamma = 1;
SVM_params.coef0 = 0;
SVM_params.C = 1;
SVM_params.nu = 0;
SVM_params.p = 0;
SVM_params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01);
printf("strat svm... \n");
//訓練
CvSVM svm;
svm.train(trainingData, classes, Mat(), Mat(), SVM_params);
//儲存模型
#if 1
svm.save("svm.xml");
cout<<"訓練好了!!!"<<endl;
getchar();
#endif
return 0;
}
void getFiles( string path, vector<string>& files )
{
long hFile = 0;
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != -1)
{
do
{
if((fileinfo.attrib & _A_SUBDIR))
{
if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
getFiles( p.assign(path).append("\\").append(fileinfo.name), files );
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
}
}while(_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
void get_2(Mat& trainingImages, vector<int>& trainingLabels)
{
char * filePath = "F:\\data\\train_image\\2";
vector<string> files;
getFiles(filePath, files );
int number = files.size();
for (int i = 0;i < number;i++)
{
Mat SrcImage=imread(files[i].c_str());
printf("files[i].c_str() = %s \n", files[i].c_str());
SrcImage= SrcImage.reshape(1, 1);
trainingImages.push_back(SrcImage);
trainingLabels.push_back(2);
}
}
void get_1(Mat& trainingImages, vector<int>& trainingLabels)
{
char * filePath = "F:\\data\\train_image\\1";
vector<string> files;
getFiles(filePath, files );
int number = files.size();
for (int i = 0;i < number;i++)
{
Mat SrcImage=imread(files[i].c_str());
printf("files[i].c_str() = %s \n", files[i].c_str());
SrcImage= SrcImage.reshape(1, 1);
trainingImages.push_back(SrcImage);
trainingLabels.push_back(1);
}
}
void get_0(Mat& trainingImages, vector<int>& trainingLabels)
{
char * filePath = "F:\\data\\train_image\\0";
vector<string> files;
getFiles(filePath, files );
int number = files.size();
for (int i = 0;i < number;i++)
{
Mat SrcImage=imread(files[i].c_str());
printf("files[i].c_str() = %s \n", files[i].c_str());
SrcImage= SrcImage.reshape(1, 1);
trainingImages.push_back(SrcImage);
trainingLabels.push_back(0);
}
}
#else if 0
#include <stdio.h>
#include <time.h>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include <io.h>
using namespace std;
using namespace cv;
void getFiles( string path, vector<string>& files );
int main()
{
int result = 0;
char * filePath = "F:\\data\\test_image\\12";
vector<string> files;
getFiles(filePath, files );
int number = files.size();
cout<< "files size: "<<number<<endl;
CvSVM svm;
svm.clear();
string modelpath = "svm.xml";
FileStorage svm_fs(modelpath,FileStorage::READ);
if(svm_fs.isOpened())
{
svm.load(modelpath.c_str());
}
for (int i = 0;i < number;i++)
{
Mat inMat = imread(files[i].c_str());
Mat p = inMat.reshape(1, 1);
p.convertTo(p, CV_32FC1);
int response = (int)svm.predict(p);
printf("result %d = %d \n",i,response);
if (response == 1)
{
result++;
}
}
cout<<"result = : "<<result<<endl;
getchar();
waitKey(0);
return 0;
}
void getFiles( string path, vector<string>& files )
{
long hFile = 0;
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != -1)
{
do
{
if((fileinfo.attrib & _A_SUBDIR))
{
if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
getFiles( p.assign(path).append("\\").append(fileinfo.name), files );
}
else
{ files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
}
}while(_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
#endif