第一步:
先是得到训练图像集
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
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的小图块
imshow("", img);
waitKey(0);
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:\\Picture1\\%d\\%d.bmp", filename, filenum++);
//先在该路径上创建文件夹名为0,1的两个文件夹,否则可能会出现错误
//sprintf_s(ad, "D:\\data\\%d\\%d.jpg", filename, filenum++);
//截取20*20的小块
Mat tmp;
gray(Range(offsetRow, offsetRow + b), Range(offsetCol, offsetCol + b)).copyTo(tmp);
imwrite(ad, tmp);
}
}
return 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;
using namespace cv::ml;
void getFiles(string path, vector<string>& files);
void get_trainingBLP(Mat& trainingImages, vector<int>& trainingLabels, char *path, int typeName);
int get_testingBLP(Mat inMat, string modelpath);
void get_trainingHOG(Mat& trainingImages, vector<int>& trainingLabels, char *path, int typeName);
Mat dealBLP(Mat inMat);
Mat dealHOG(Mat inMat);
void TrainSVM(Mat traingImage, vector<int> trainLabel,string filename);
int get_testingHOG(Mat inMat, string modelpath);
int main()
{
//Mat classes;
vector<int> trainingLabels;
Mat trainingImages;
Mat testingImages = Mat(Size(28, 28), CV_8UC3);
//get_trainingBLP(trainingImages, trainingLabels, "D:\\data\\0", 0);
//get_trainingBLP(trainingImages, trainingLabels, "D:\\data\\1", 1);
//"D:\\data\\0"该路径中包含了所有0图片的路径
get_trainingHOG(trainingImages, trainingLabels, "D:\\data\\0", 0);
get_trainingHOG(trainingImages, trainingLabels, "D:\\data\\1", 1);
TrainSVM(trainingImages, trainingLabels,"svm1.xml");
int result = 0;
char* filePath = "F:\\Picture\\0";
vector<string> files;
getFiles(filePath, files);
int number = files.size();
cout << "\n\n总共有 " << number << " 个测试图像";
for (int i = 0; i < number; i++)
{
Mat inMat = imread(files[i].c_str());
//int r = get_testingBLP(inMat, "svm.xml");
resize(inMat, testingImages, testingImages.size());
int r = get_testingHOG(testingImages, "svm1.xml");
if (r == 0)
{
result++;
}
}
cout << "\n总共 " << result << " 个0" << endl;
Mat src = imread("E:/1.jpg");
imshow("ok", src);
waitKey(0);
}
void TrainSVM(Mat traingImage,vector<int> trainLabel,string filename)
{
Mat trainingData;
Mat classes;
Mat(traingImage).copyTo(trainingData);
trainingData.convertTo(trainingData, CV_32FC1);
Mat(trainLabel).copyTo(classes);
Ptr<SVM> model = SVM::create();
model->setType(SVM::C_SVC);
model->setKernel(SVM::LINEAR);
model->setDegree(0);
model->setGamma(1);
model->setCoef0(0);
model->setC(1);
model->setNu(0);
model->setP(0);
model->setTermCriteria(CvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01));
Ptr<TrainData> tData = TrainData::create(trainingData, ROW_SAMPLE, classes);
model->train(tData);
model->save(filename);
cout << "训练好了!!!!!" << endl;
}
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_trainingBLP(Mat& trainingImages, vector<int>& trainingLabels, char *path, int typeName)
{
char *filePath = path;
vector<string> files;
getFiles(filePath, files);
int number = files.size();
for (int i = 0; i < number; i++)
{
cout << "\n训练 " << typeName << " 的第 " << i << " 次循环\n" << endl;
Mat SrcImage = imread(files[i].c_str());
SrcImage = dealBLP(SrcImage);
trainingImages.push_back(SrcImage);
trainingLabels.push_back(typeName);
cout << " 处理完毕: " << files[i].c_str() << endl;
}
}
void get_trainingHOG(Mat& trainingImages, vector<int>& trainingLabels, char *path, int typeName)
{
char *filePath = path;
vector<string> files;
getFiles(filePath, files);
int number = files.size();
cout << " 共样本个数为:" << number << endl;
Mat data_mat, labels_mat;
data_mat = Mat::zeros(number, 324, CV_32FC1);
labels_mat = Mat::zeros(number, 1, CV_32SC1);
Mat src;
Mat trainImg = Mat(Size(28, 28), CV_8UC3);
for (int i = 0; i < number; i++)
{
cout << "\n训练 " << typeName << " 的第 " << i << " 次循环\n" << endl;
Mat SrcImage = imread(files[i].c_str());
resize(SrcImage, trainImg, trainImg.size());
Mat hogMat = dealHOG(trainImg);
//for (int j = 0; j < hogMat.cols; j++)
//{
// data_mat.at<float>(i, j) = hogMat.at<float>(0,j);
//}
trainingImages.push_back(hogMat);
trainingLabels.push_back(typeName);
cout << " 处理完毕: " << files[i].c_str() << endl;
}
}
Mat dealHOG(Mat inMat)
{
Mat result = Mat::zeros(1, 324, CV_32FC1);
HOGDescriptor *hog = new HOGDescriptor(Size(28, 28), Size(14, 14), Size(7, 7), Size(7, 7), 9);
vector<float>descriptors;//存放结果 为HOG描述子向量
hog->compute(inMat, descriptors, Size(1, 1), Size(0, 0)); //Hog特征计算,检测窗口移动步长(1,1)
//cout << "HOG描述子向量个数 : " << descriptors.size() << endl;
int number = descriptors.size();
for (int n = 0; n < number; n++)
{
result.at<float>(0,n) = descriptors[n];//第1个样本的特征向量中的第n个元素
}
return result;
}
Mat dealBLP(Mat inMat)
{
Mat gray_src;
cvtColor(inMat, gray_src, CV_BGR2GRAY);
Mat lbpImage = Mat::zeros(gray_src.rows - 2, gray_src.cols - 2, CV_8UC1);
for (int row = 1; row < gray_src.rows - 1; row++) {
for (int col = 1; col < gray_src.cols - 1; col++) {
uchar c = gray_src.at<uchar>(row, col);
uchar code = 0;
code |= (gray_src.at<uchar>(row - 1, col - 1) > c) << 7;
code |= (gray_src.at<uchar>(row - 1, col) > c) << 6;
code |= (gray_src.at<uchar>(row - 1, col + 1) > c) << 5;
code |= (gray_src.at<uchar>(row, col + 1) > c) << 4;
code |= (gray_src.at<uchar>(row + 1, col + 1) > c) << 3;
code |= (gray_src.at<uchar>(row + 1, col) > c) << 2;
code |= (gray_src.at<uchar>(row + 1, col - 1) > c) << 1;
code |= (gray_src.at<uchar>(row, col - 1) > c) << 0;
lbpImage.at<uchar>(row - 1, col - 1) = code;
}
}
Mat outMat = lbpImage.reshape(1, 1);
outMat.convertTo(outMat, CV_32FC1);
return outMat;
}
int get_testingBLP(Mat inMat, string modelpath)
{
int result = 0;
Ptr<SVM> model;
FileStorage svm_fs(modelpath, FileStorage::READ);
if (svm_fs.isOpened())
{
model = StatModel::load<SVM>(modelpath);
}
Mat SrcImage = dealBLP(inMat);
int response = (int)model->predict(SrcImage);
return response;
}
int get_testingHOG(Mat inMat, string modelpath)
{
int result = 0;
Ptr<SVM> model;
FileStorage svm_fs(modelpath, FileStorage::READ);
if (svm_fs.isOpened())
{
model = StatModel::load<SVM>(modelpath);
}
Mat SrcImage=dealHOG(inMat);
int response = (int)model->predict(SrcImage);
return response;
}