The realization of OPENCV's CVSVM is based on LIBSVM,LIBSVM, a world-famous SVM library written by Professor Lin Chih-jen of Taiwan University (probably the most widely used library in the industry today). The input of SVM's Perdict method is the characteristic of the data to be predicted, also called features. Here, we enter a feature that is all pixels of the image. Since SVM requires that the input should be a vector, and mat is a matrix corresponding to the width of the image, we need to use the reshape (1,1) method to stretching into the vector before entering.
Before training, we must first classify the samples to be trained, one is the license plate image, the other is the non license plate picture, which can be called the positive sample and the reverse sample, and the classification process will take a lot of time to do. After classification, we can put the positive sample and inverse sample into the program, and do a good job of preprocessing, the specific code is as follows:
<span style= "Background-color:rgb (240, 240, 240);" >//first define two global variables </span>
Vector<mat> trainingimages;
Vector<int> Traininglabels;
--------------file reads--------------------void File_open (string filedir,int flag) {long LF;
vector<string> files;
_finddata_t file;
string path; if (lf = _findfirst (path.assign (Filedir). Append ("\\*"). C_str (), &file)) = = 1) {cout << "file not found!" &
lt;< Endl; else {while (_findnext (LF, &file) = = 0)//loop All files in the folder, but there is no subfolder check {if (strcmp (File.name, "...") = = 0 ) continue;
Remove the first unwanted filename "..." Files.push_back (Path.assign (Filedir). append ("\ \"). Append (File.name));
File path + filename saved to files//cout << file.name << Endl; } _findclose (LF);
Close File lookup cout << "The number of file is:" << files.size () << Endl;
int size = Files.size ();
if (0 = size) cout << "No File Found in train hasplate!" << Endl;
for (int i = 0; I <files.size (); i++)//{Mat img = imread (FILES[I].C_STR ());
Imshow ("Adad", IMG); Mat line_i = Img.reshape (1, 1);
One dimension of the image to be trained (if it is to extract the characteristics of the image to learn, but also need to be a one-dimensional feature to use SVM to learn)Trainingimages.push_back (line_i); The one-dimensional img is saved Traininglabels.push_back (flag); corresponding category identification}}
Here flag parameter is passed over the corresponding training picture identification, if 1 is a positive sample, if 0 is the inverse example, in the study, it is best to put the positive example and the reverse example under the folder, and the image size is the same.
In fact, this is the image of all the pixels as a feature of the training, the effect is not very good, the results of the experiment is probably only more than 80% of the correct rate, should find better characteristics for training.
When the image is read, it is invoked in the main function, as follows:
Mat classes;//Save all positive and negative sample class superscript
char * filedir = "e:\\data\\plate_detect_svm\\learn\\hasplate";//the path of the positive sample
File_open ( Filedir, 1); Positive sample file read
Filedir = "e:\\data\\plate_detect_svm\\learn\\noplate";//Negative sample path
file_open (filedir, 0);//Negative sample file Read
cout << trainingimages[0].cols << "number" <<trainingimages.size () << Endl;
Mat Trainingdata (Trainingimages.size (), Trainingimages[0].cols, CV_32FC1);//To hold all positive and negative sample pictures or features for
(int i = 0; i< Trainingimages.size (); i++)//To save each one-dimensional training image to Trainingdata
{
Mat temp (trainingimages[i));
Temp.copyto (Trainingdata.row (i));//deposit to Trainingdata on line i
}
//trainingdata.convertto (Trainingdata, CV_ 32FC1);
Mat (traininglabels). CopyTo (classes);
Classes.convertto (classes, CV_32FC1); <span style= "font-family:arial, Helvetica, Sans-serif;" >//into the format of SVM requirements </span>
The following is the SVM parameter setup and training:
SVM parameter setting, here the parameter is many, the setting is good or bad directly affects the study result
cvsvmparams svm_params;
Svm_params.svm_type = cvsvm::c_svc;
Svm_params.kernel_type = Cvsvm::linear; 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);
Start Training (learning)
CVSVM SVM (trainingdata, classes, Mat (), Mat (), svm_params);
Save Training Model
Filestorage fsto ("E:/data/svm_plate.xml", filestorage::write);
Svm.write (*fsto, "SVM");
Finally, take a picture to test:
void Test ()
{
CVSVM SVM;
Svm.clear ();
Svm.load ("E:\\data\\svm_plate.xml");
Mat test_img = Imread ("e:\\data\\plate_detect_svm\\test\\hasplate\\a03_aaq839_3.jpg");
Mat line_test_img = Test_img.reshape (1, 1);
Line_test_img.convertto (line_test_img, CV_32FC1);
int response = (int) svm.predict (line_test_img);
if (response = = 1)
cout << "is the license plate" << Endl;
else
cout << "not license plate" << Endl;
}
Because the exact recognition rate of the training results cannot be tested with just one picture, you need to use the loop to call the test () function, and record the success rate of tests, and to know the success rate must have a predetermined test set to test, this step is not difficult, we must be able to achieve.