[EmguCV] C # Implementation of HOG and SVM,
About the alpha and rock vectors in SVM
EmguCV encapsulation is more thorough. in C #, the two intermediate variables cannot be obtained through reload like C ++.
// Inherit from the CvSVM class, because the decision_func parameter of the trained SVM must be used to generate the detection sub-parameters used in setSVMDetector, // However, by viewing the CvSVM source code, we can see that the decision_func parameter is a protected type variable and cannot be accessed directly. You can only access class MySVM: public CvSVM {public: // obtain the double * get_alpha_vector () {return this-> decision_func-> alpha;} from the alpha array in the decision-making function of SVM. // obtain the ROV parameter in the decision-making function of SVM, that is, the offset float get_rov () {return this-> decision_func-> ROV ;}};
See the C ++ example: training SVM classifier for HOG Pedestrian detection.Http://blog.csdn.net/pb09013037/article/details/41256945)
To get these two variables for custom HOG detection, you can think of the following methods:
1. C # Read the generated XML file
After the classifier is trained, it is generally saved for direct prediction.
SVM svm = new SVM();bool trained = svm.Train(my_train.sampleFeatureMat, my_train.sampleLabelMat, null, null, p);svm.Save(@"../HOG_SVM.xml");
Here is my C # Method for Extracting SVM parameters:
(It is only used to extract XML files whose training target is 1 and-1. If the type is greater than 2, there will be more than one arrays of rock and alpha, which need to be further combined)
using System;using System.Text;using System.Xml;using System.IO;namespace HOG_SVM{ class GetData { public double[] alpha; public double rho; XmlDocument doc; StreamReader sr; int sv_count; string alpha_str; public GetData() { doc = new XmlDocument(); doc.Load(Form1.LOAD_PATH); XmlNode nodes = doc.DocumentElement; get_rho(nodes); getAlpha_str(nodes); getSv_count(nodes); getAlpha(); } public void get_rho(XmlNode nodes) { if (nodes.HasChildNodes) { foreach (XmlNode node in nodes.ChildNodes) { if (nodes.Name == "rho") { rho = Double.Parse(nodes.InnerText); return; } get_rho(node); } } } public void getAlpha_str(XmlNode nodes) { if (nodes.HasChildNodes) { foreach (XmlNode node in nodes.ChildNodes) { if (nodes.Name == "alpha") { //sr = new StreamReader(new Stream(nodes.InnerText)); alpha_str = nodes.InnerText; return; } getAlpha_str(node); } } } public void getSv_count(XmlNode nodes) { if (nodes.HasChildNodes) { foreach (XmlNode node in nodes.ChildNodes) { if (nodes.Name == "sv_count") { sv_count = int.Parse(nodes.InnerText); return; } getSv_count(node); } } } public void getAlpha() { byte[] array = Encoding.ASCII.GetBytes(alpha_str); MemoryStream stream = new MemoryStream(array); //convert stream 2 string sr = new StreamReader(stream); alpha = new double[sv_count]; sr.ReadLine(); int i = 0; while (true) { string tmp = sr.ReadLine(); if (tmp == "") continue; string[] tmp2 = tmp.Split(' '); foreach (string ele in tmp2) { if (ele != "") { alpha[i] = double.Parse(ele); i++; } } if (i == sv_count) break; } } }}
C # There are many ways to read XML. You can also use Linq to operate xml. You can also refer to the following link:
C # Read the xml classifier trained by svm generated by opencv:Http://blog.csdn.net/yeyang911/article/details/12905153
2. Use other C # SVM Libraries
The question about Parameter Extraction and custom HOG Detector was found on the Internet.
Training custom SVM to use with HOGDescriptor in OpenCV:
I was struggling with the same problem. searching forums I have found, that the detector cannot be trained using CvSVM (I don't know the reason ). I used LIBSVM for training the detector. here is the code to extract the detector for HOGDescriptor. setSVMDetector (w): For data details see LIBSVM documentation/header. I did all the training in C ++, filling the LIBSVM training data from CV to LIBSVM; the code below extracts the detector vector needed for cv: HOGDescriptor. the w parameter isstd::vector<float> w |
const double * const *sv_coef = model.sv_coef;const svm_node * const *SV = model.SV;int l = model.l;model.label;const svm_node* p_tmp = SV[0];int len = 0;while( p_tmp->index != -1 ){ len++; p_tmp++;}w.resize( len+1 );for( int i=0; i<l; i++){ double svcoef = sv_coef[0][i]; const svm_node* p = SV[i]; while( p->index != -1 ) { w[p->index-1] += float(svcoef * p->value); p++; }}w[len] = float(-model.rho[0]); |
From:Http://stackoverflow.com/questions/15339657/training-custom-svm-to-use-with-hogdescriptor-in-opencv
The LIBSVM Library mentioned in this answer is a good alternative. You should be able to directly obtain the intermediate values without parsing XML.
You can download it on the author's homepage.LIBSVMLibrary:Http://www.csie.ntu.edu.tw /~ Cjlin/libsvm/# csharp
3. Other Related Links
- In the previous days, [OpenCV] pedestrian detection Learning Based on HOG and SVM (Principle summary ):
Http://www.cnblogs.com/KC-Mei/p/4534009.html
- Training GPU HOGDescriptor for multi scale detection:
Http://answers.opencv.org/question/4351/training-gpu-hogdescriptor-for-multi-scale-detection/