There are some very good articles on the hog+svm,csdn, here give me think write a few of the better, for everyone to reference
Hog characteristics of Image feature extraction from target detection
HOG: From theory to OPENCV practice
OPENCV Learning Notes-Getting Started (21) three linear interpolation-hog (ii)
This blog is written about three linear interpolation, in order to reduce the aliasing effect, write well
Classification of HOG+SVM objects in OpenCV
OpenCV Hogdescriptor parametric plot
Pedestrian detection using hog feature and SVM classifier
The above is a personal feel to write a better blog, basically the above blog to understand, Hog also more understanding, if you want to enter to understand hog, suggest directly see OPENCV hog source
Now, let's talk about two ways to implement pedestrian detection using the HOG+SVM in OpenCV
Description: The program running environment is vs2013+opencv3.0 the first kind
The first way, directly on the code:
HOG+SVM recognition Method 2///////////////////////////////////////////////////void Train () {
Read the Training sample picture path and category/////////////////////////////////////////////////////image path and category
Vector<string> ImagePath;
Vector<int> Imageclass;
int numberofline = 0;
string buffer;
Ifstream trainingdata (String (FILEPATH) + "TrainData.txt");
unsigned long n;
while (!trainingdata.eof ()) {getline (trainingdata, buffer);
if (!buffer.empty ()) {++numberofline; if (numberofline% 2 = = 0) {//Read sample class Imageclass.push_back (Atoi (Buffer.c_str ()
));
} else {//Read image path Imagepath.push_back (buffer);
}}}//Close file Trainingdata.close ();
Gets the hog characteristics of the sample///////////////////////////////////////////////////Sample feature vector matrix int numberofsample = NUMBEROFLINE/2; Mat Featurevectorofsample (Numberofsample, 3780, CV_32FC1);//matrix each behavior one sample//sample category Mat Classofsample (Numberofsample,
1, CV_32SC1);
Mat Convertedimage;
Mat Trainimage;
Calculates the hog feature for (vector<string>::size_type i = 0; I <= imagepath.size ()-1; ++i) {//read in picture
Mat src = imread (imagepath[i],-1);
if (Src.empty ()) {cout << "can not load the image:" << imagepath[i] << Endl;
Continue
}//cout << "Processing:" << imagepath[i] << Endl;
Normalized resize (src, trainimage, Size (64, 128));
Extract Hog features Hogdescriptor hog (cvsize (8, 8), Cvsize (8, 8), cvsize (9);
vector<float> descriptors;
Double time1 = GetTickCount (); Hog.compute (Trainimage, descriptors);//Here you can set the detection window step, if the picture size is more than 64x128, you can set the winstride double time2 = GetTickCount ();
Double Elapse_ms = (time2-time1) * 1000/gettickfrequency ();
cout << "HOG Dimensions:" << descriptors.size () << Endl;
cout << "Compute time:" << Elapse_ms << Endl;
Save to Eigenvectors Matrix for (Vector<float>::size_type j = 0; J <= descriptors.size ()-1; ++j) {
Featurevectorofsample.at<float> (i, j) = Descriptors[j]; }//Save category to category matrix//!!
Note the category type must be classofsample.at<int> of type int (i, 0) = Imageclass[i]; }///////////////////////////////////Training/////////////////////////////////////////////////////setting parameters using the SVM classifier, note
Use of Ptr ptr<svm> SVM = Svm::create ();
Svm->settype (SVM::C_SVC);
Svm->setkernel (svm::linear);//Note You must use linear SVM for training, because the hogdescriptor detection function only supports linear detection ...
Svm->settermcriteria (Termcriteria (Cv_termcrit_iter, Flt_epsilon)); Use SVM to learn Svm->train (Featurevectorofsample, ROW_sample, classofsample);
Save classifier (includes SVM parameters, support vector, α and Rho) Svm->save (String (FILEPATH) + "Classifier.xml");
/* In the XML file obtained after the SVM training, there is an array called the support vector, and an array called alpha, with a floating-point number called Rho; Multiply the alpha matrix with the support vector, and note that Alpha*supportvector will get a line vector that multiplies the front of the vector by-1.
After that, the line is then added to the last element of the vector rho. So, become a classifier, using the classifier, directly replace the OPENCV in the pedestrian detection default that classifier (Cv::hogdescriptor::setsvmdetector ()), *///Get support vector machine: Matrix default is cv_32f Mat
Supportvector = Svm->getsupportvectors ();//Get Alpha and Rho Mat alpha;//each support vector corresponding to the parameter α (Lagrange multiplier), the default alpha is float64
Mat svindex;//Support Vector index float rho = svm->getdecisionfunction (0, Alpha, svindex);
Conversion type: Be sure to note that the Mat alpha2 needs to be converted to 32;
Alpha.convertto (ALPHA2, CV_32FC1);
Result matrices, two matrices multiplied by Mat result (1, 3780, CV_32FC1);
result = Alpha2*supportvector;
Multiply-1, why is it multiplied by-1 here? Note that because Svm.predict is using Alpha*sv*another-rho, if negative it is considered a positive sample, in Hog's detection function, use Rho+alpha*sv*another (another is-1) for (int i = 0; i < 3780; ++i) Result.at<floaT> (0, I) *=-1; Save the classifier to a file for easy HOG identification//This is the true discriminant function parameter (ω), HOG can directly use this parameter to identify the file *FP = fopen ((string (FILEPATH) + "Hog_svm.txt"). C_str
(), "WB");
for (int i = 0; i<3780; i++) {fprintf (FP, "%f \ n", result.at<float> (0,i));
} fprintf (FP, "%f", rho);
Fclose (FP);
}//Use a well-trained classifier to identify void Detect () {Mat img;
file* f = 0;
Char _filename[1024];
Gets the test picture file path F = fopen ((string (FILEPATH) + "TestData.txt"). C_str (), "RT");
if (!f) {fprintf (stderr, "error:the specified file could not being loaded\n");
Return
}//Load the parameters of the well-trained discriminant function (note, unlike Svm->save-saved classifiers) vector<float> detector;
Ifstream Filein (String (FILEPATH) + "Hog_svm.txt", ios::in);
float val = 0.0f;
while (!filein.eof ()) {Filein >> val;
Detector.push_back (Val);
} filein.close ();
Set Hog Hogdescriptor hog; Hog.setsvmdetector (detector);//Use your own training classifier//hog.setsvmdetector (hogDescriptor::getdefaultpeopledetector ());//You can use the CVPR trained classifier directly, so you don't have to train () This step Namedwindow ("People detector", 1
);
Detect picture for (;;)
{//read filename char* filename = _filename;
if (f) {if (!fgets (filename, (int) sizeof (_filename)-2, F)) break;
while (*filename && isspace (*filename))//++filename;
if (filename[0] = = ' # ') continue;
Remove space int l = (int) strlen (filename);
while (L > 0 && isspace (filename[l-1]))--l;
Filename[l] = ' + ';
img = imread (filename);
} printf ("%s:\n", filename);
if (!img.data) continue;
Fflush (stdout);
Vector<rect> found, found_filtered;
Double T = (double) getTickCount (); Run the detector with default parameters. To get a higher hit-rate//(+ More False AlArms, respectively), decrease the hitthreshold and//Groupthreshold (set Groupthreshold to 0 to turn off the Grou
Ping completely).
Multiscale detection Hog.detectmultiscale (IMG, found, 0, size (8, 8), size (32, 32), 1.05, 2);
t = (double) getTickCount ()-t;
printf ("Detection time =%gms\n", t*1000./cv::gettickfrequency ());
size_t I, J;
Remove areas with internal and external inclusions in space, preserving large for (i = 0; i < found.size (); i++) {Rect r = found[i];
for (j = 0; J < Found.size (); j + +) if (j! = I && (R & found[j]) = = R) break;
if (j = = Found.size ()) Found_filtered.push_back (R); }//suitably narrow rectangle for (i = 0; i < found_filtered.size (); i++) {Rect r = found_filtered[
I];
The HOG detector returns slightly larger rectangles than the real objects. So we slightly shrink the rectangles to get a nicer outPut.
R.x + = Cvround (r.width*0.1);
R.width = Cvround (r.width*0.8);
R.y + = Cvround (r.height*0.07);
R.height = Cvround (r.height*0.8);
Rectangle (img, r.tl (), R.Br (), cv::scalar (0, 255, 0), 3);
} imshow ("People Detector", IMG);
int c = Waitkey (0) & 255;
if (c = = ' Q ' | | c = = ' Q ' | |!f) break;
} if (f) fclose (f);
Return
} void Hog_svm2 () {///if using the default classifier provided by CVPR, you do not need to Train (), use detect to detect the image Train () directly;
Detect ();
} int main () {//HOG+SVM recognition Mode 1: Direct output category//HOG_SVM1 ();
HOG+SVM Recognition Method 2: The output picture of the existence of the target rectangle hog_svm2 (); }
Here I would like to explain TrainData.txt, this file places all the sample paths and categories, as follows:
Off
In how to read the path of the positive and negative samples to the TXT file, you can use batch files, batch files I uploaded to the csdn, you can go to download
Click to download
The positive and negative samples are guaranteed to be at least 1000, not too little, otherwise the effect is not good, wherein the hog_svm.txt contains the parameters of the discriminant function, this parameter can be used directly to hog
Here is my test result:
The detection effect is also possible.
Test picture I've uploaded it to the Internet.
Click to download
Of course, you can also do not have to train the classifier, directly using the OpenCV of the classifier, OpenCV comes with the classifier used in the 05 CVPR that article the author trained classifier, the following we will look at the effect:
As can be seen in the figure, OpenCV comes with the classifier effect than their own training good, the main reason is probably the following points
1. Training sample is not enough, my positive and negative samples are more than 900
2. Positive sample image is not clear enough, resulting in a large error in feature extraction
Recently, someone ran a program in the blog when there is a problem, let me see the program, I do not know what the problem, so I have the entire program and program test data package, uploaded to the csdn.
Click to download
After unpacking, place the "pedestrians64x128" folder in the D packing directory, and then use HOG.cpp to create a new project that can be run directly.
Note: Environment is the second type of vs2013+opencv3.0.0,release version
Here's the second way, the second way is the traditional way, that is, for the test sample, extract the features, and then use a well-trained classifier to identify, code
HOG+SVM recognition method 1///////////////////////////////////////////////////void Hog_svm1
() {////////////////////////////////read in training sample picture path and category/////////////////////////////////////////////////////image path and category
Vector<string> ImagePath;
Vector<int> Imageclass;
int numberofline = 0;
string buffer;
Ifstream trainingdata (String (FILEPATH) + "TrainData.txt", ios::in);
unsigned long n;
while (!trainingdata.eof ()) {getline (trainingdata, buffer);
if (!buffer.empty ()) {++numberofline; if (numberofline% 2 = = 0) {//Read sample class Imageclass.push_back (Atoi (Buffer.c_str ()
));
} else {//Read image path Imagepath.push_back (buffer);
}}} trainingdata.close (); Get the hog characteristics of a sample/////////////////////////////////////////////////////Sample feature vector matrix int numberofsample = NUMBEROFLINE/2; Mat Featurevectorofsample (Numberofsample, 3780, CV_32FC1);//matrix each behavior one sample//sample category Mat Classofsample (Numberofsample,
1, CV_32SC1);
Start calculating the Hog feature for the Training sample for (Vector<string>::size_type i = 0; I <= imagepath.size ()-1; ++i) {//read in picture
Mat src = imread (imagepath[i],-1);
if (Src.empty ()) {cout << "can not load the image:" << imagepath[i] << Endl;
Continue
} cout << "Processing" << Imagepath[i] << Endl;
Scale Mat Trainimage;
Resize (src, trainimage, Size (64, 128));
Extract Hog features Hogdescriptor hog (size (+), size (8, 8), size (8, 8), 9);
vector<float> descriptors; Hog.compute (Trainimage, descriptors);//Here you can set the detection window step, if the picture size is more than 64x128, you can set winstride cout << "Hog Dimensions:" &
lt;< descriptors.size () << Endl;Save the feature vector matrix for (Vector<float>::size_type j = 0; J <= descriptors.size ()-1; ++j) {
Featurevectorofsample.at<float> (i, j) = Descriptors[j]; }//Save category to category matrix//!!
Note the category type must be classofsample.at<int> of type int (i, 0) = Imageclass[i];
}///////////////////////////////////Training/////////////////////////////////////////////////////setting parameters using the SVM classifier
Reference 3.0 of the demo ptr<svm> SVM = Svm::create ();
Svm->setkernel (SVM::RBF);
Svm->settype (SVM::C_SVC);
SVM->SETC (10);
SVM->SETCOEF0 (1.0);
SVM->SETP (1.0);
SVM->SETNU (0.5);
Svm->settermcriteria (Termcriteria (Cv_termcrit_eps, Flt_epsilon));
Use SVM to learn Svm->train (Featurevectorofsample, Row_sample, classofsample);
Save classifier Svm->save ("Classifier.xml"); Use a well-trained classifier to identify///////////////</