The feature we used in the last article is all pixel values of training samples , Convenient but not accurate .

This article mainly introduces the use of SVM+HOG Features recognize numbers .

Please see the last article for details , The main difference between them is the training samples HOG Feature extraction , The rest is basically the same , So I attached the code directly .

The following code is opencv3 and C++

You can modify the training sample category according to your own needs , number , size .oss Training sample path based on ,src Detection image path for .
#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>
// Find file related functions using namespace std; using namespace cv; using namespace ml;
ostringstream oss;// Combining strings and numbers int num = -1; Mat dealimage; Mat src; Mat
yangben_gray; Mat yangben_thresh; void feature(Mat dealimage);
////=============================== Read training data ===============================////
const int classsum = 10;// Training pictures in common 10 class , Modifiable const int imagesSum =
500;// Each category has 500 Pictures , Modifiable int yangben_data_position = -1; Mat data_mat =
Mat(classsum*imagesSum, 8100, CV_32FC1);
//data_mat Used to save all training samples HOG features , Each column is an image HOG features // Every behavior, every training image // Must be CV_32FC1 Type of
// That's ok , column , type ; Second parameter , That is, the columns of the matrix are composed of descriptors The size of the ,
// It can be done by descriptors.size() obtain , And for different sizes of input training pictures , This value is different //descriptors For the extracted HOG features int
main() { // Training data , One training picture per line Mat trainingData; // Training sample label Mat labels; // Final training sample label
Mat clas; // Final training data Mat traindata;
////////////////////// Extract pictures from specified folder ////////////////// for (int p = 0; p <
classsum; p++)// Extract in turn 0 reach 9 Pictures in folder { oss <<
"C:/Users/zhang/Desktop/opencv—— example / Small cases / License plate detection / Based on machine learning / Template matching sample /"; num += 1;//num from 0 reach 9
int label = num; oss << num << "/*.jpg";// Image name suffix ,oss You can combine numbers with strings string pattern =
oss.str();//oss.str() output oss character string , And give pattern oss.str("");// After each cycle oss String empty
vector<Mat> input_images; vector<String> input_images_name; glob(pattern,
input_images_name, false); // by false Time , Only traverse the files that conform to the pattern in the specified folder , should be true Time , The subfolders of the specified folder are traversed at the same time
// here input_images_name Address for storing qualified pictures int all_num = input_images_name.size();
// How many pictures are there under the file //cout << num << ": All in all " << all_num << " Pictures to be tested " << endl; for (int i
= 0; i < imagesSum; i++)// Loop through the pictures in each folder in turn {
cvtColor(imread(input_images_name[i]), yangben_gray, COLOR_BGR2GRAY);// Gray scale transformation
threshold(yangben_gray, yangben_thresh, 0, 255, THRESH_OTSU);// Binarization
// Loop through each image and place it in the vector<Mat> input_images within
input_images.push_back(yangben_thresh); dealimage = input_images[i];
// Yes HOG To complete the feature extraction yangben_data_position += 1;// Which image is represented by
feature(dealimage);// Image feature extraction labels.push_back(label);// Save the tags corresponding to each picture in turn cout <<
" The first " << yangben_data_position << " The sample is being extracted HOG features " << endl; } } cout <<
" Sample feature extraction is completed , Waiting to be created SVM Model " << endl;
////=============================== establish SVM Model ===============================////
// Create classifier and set parameters Ptr<SVM> SVM_params = SVM::create();
SVM_params->setType(SVM::C_SVC);//C_SVC For classification ,C_SVR For regression
SVM_params->setKernel(SVM::LINEAR); //LINEAR Linear kernel function .SIGMOID Is a Gaussian kernel function
SVM_params->setDegree(0);// Parameters in kernel functions degree, For polynomial kernel functions ;
SVM_params->setGamma(1);// Parameters in kernel functions gamma, For polynomials /RBF/SIGMOID kernel function ;
SVM_params->setCoef0(0);// Parameters in kernel functions , For polynomials /SIGMOID kernel function ;
SVM_params->setC(1);//SVM Optimal problem parameters , set up C-SVC,EPS_SVR and NU_SVR Parameters of ;
SVM_params->setNu(0);//SVM Optimal problem parameters , set up NU_SVC, ONE_CLASS and NU_SVR Parameters of ;
SVM_params->setP(0);//SVM Optimal problem parameters , set up EPS_SVR Medium loss function p Value of . // End condition , Training 1000 Times or error less than 0.01 end
SVM_params->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER +
TermCriteria::EPS, 1000, 0.01)); // Combination of training data and Tags Ptr<TrainData> tData =
TrainData::create(data_mat, ROW_SAMPLE, labels); // Training classifier
SVM_params->train(tData);// train // Save model
SVM_params->save("C:/Users/zhang/Desktop/opencv—— example / Small cases / License plate detection / Based on machine learning / character recognition svm.xml");
cout << " Training is done !!!" << endl; cout << " Waiting for identification " << endl;
////=============================== Forecast part ===============================//// Mat
src =
imread("C:/Users/zhang/Desktop/opencv—— example / Small cases / License plate detection / Based on machine learning / License plate characters detected / character 7.jpg");
cvtColor(src, src, COLOR_BGR2GRAY); threshold(src, src, 0, 255,
CV_THRESH_OTSU); imshow(" Original image ", src); // Feature points of input image Mat trainTempImg =
Mat::zeros(Size(128, 128), CV_8UC1); resize(src, trainTempImg,
trainTempImg.size()); HOGDescriptor *hog = new HOGDescriptor(Size(128, 128),
Size(16, 16), Size(8, 8), Size(8, 8), 9); vector<float>descriptors;// Result array
hog->compute(trainTempImg, descriptors, Size(1, 1), Size(0, 0)); //cout <<
"HOG Dimension of descriptors " << descriptors.size() << endl; Mat SVMtrainMat = Mat(1,
descriptors.size(), CV_32FC1); int number1 = descriptors.size();
// Will be calculated HOG The descriptor is copied to the sample feature matrix SVMtrainMat for (int i = 0; i < number1; i++) {
// Put an image of HOG The descriptors are stored in sequence data_mat Same column of matrix // Because there is only one input image , Namely SVMtrainMat There is only one column , Then it is 0<float>(0, i) = descriptors[i]; // n++; }
SVMtrainMat.convertTo(SVMtrainMat, CV_32FC1);// Change the type of picture data , necessary , Otherwise it will go wrong int ret =
(int)SVM_params->predict(SVMtrainMat);// detection result cout << " The numbers identified are :" << ret << endl;
waitKey(0); return 0; } void feature(Mat dealimage) {
// Enlarge the training sample to 128,128. easy HOG Feature extraction Mat trainImg = Mat(Size(128, 128), CV_8UC1);
resize(dealimage, trainImg, trainImg.size()); // handle HOG features
// Detection window (64,128), Block size (16,16), Block step size (8,8),cell size (8,8), histogram bin number 9 , It needs to be modified HOGDescriptor
*hog = new HOGDescriptor(Size(128, 128), Size(16, 16), Size(8, 8), Size(8, 8),
9); vector<float>descriptors;// Storage results by HOG Descriptor vector hog->compute(trainImg,
descriptors, Size(1, 1), Size(0, 0)); //Hog Feature calculation , Detection window moving step size (1,1) //cout <<
"HOG Dimension of descriptors : " << descriptors.size() << endl; for (vector<float>::size_type j
= 0; j < descriptors.size(); j++) { // Put an image of HOG The descriptors are stored in sequence data_mat Same column of matrix<float>(yangben_data_position, j) = descriptors[j]; } }

Identification results :

©2019-2020 Toolsou All rights reserved,
c Language implementation 《 Student management system 》 No hole is the future of mobile phone ? There are still many problems to be solved Junior , A little sense , Just for mutual encouragement How to use Vue Used in Echarts Visual Library The 11th Blue Bridge Cup Java The second provincial competition B Group part Python- be based on OpenCV Contour fill for flooding algorithm hole filling 【C#】 The realization of student achievement information management system List Common interview questions in the collection and simple ideas China Mobile Science Popularization : Why do mobile networks call “ Cellular mobile network ”【Golang Basic series 10 】Go language On conditional sentences if