Training custom SVM to use with HOGDescriptor in OpenCV

前端 未结 3 717
盖世英雄少女心
盖世英雄少女心 2020-11-30 07:25

I\'m trying to train my own detector for use with OpenCV::HOGDescriptor but I\'m having trouble making the existing HOGDescriptor work with my newly trained SVM.

I

相关标签:
3条回答
  • 2020-11-30 07:34

    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 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 is std::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]);
    

    Hope this helps...

    0 讨论(0)
  • 2020-11-30 07:39

    I wrote a child class of CvSVM to extract primal form after a linear svm is trained. Positive samples are labeled 1 and negative samples are labeled -1. It is strange that I have to put negative sign in front of alphas and leaving the sign of rho unchanged in order to get correct results from HogDescriptor.

    LinearSVM.h

    #ifndef LINEAR_SVM_H_
    #define LINEAR_SVM_H_
    #include <opencv2/core/core.hpp>
    #include <opencv2/ml/ml.hpp>
    
    class LinearSVM: public CvSVM {
    public:
      void getSupportVector(std::vector<float>& support_vector) const;
    };  
    
    #endif /* LINEAR_SVM_H_ */
    

    LinearSVM.cc

    #include "linear_svm.h"    
    void LinearSVM::getSupportVector(std::vector<float>& support_vector) const {
    
        int sv_count = get_support_vector_count();
        const CvSVMDecisionFunc* df = decision_func;
        const double* alphas = df[0].alpha;
        double rho = df[0].rho;
        int var_count = get_var_count();
        support_vector.resize(var_count, 0);
        for (unsigned int r = 0; r < (unsigned)sv_count; r++) {
          float myalpha = alphas[r];
          const float* v = get_support_vector(r);
          for (int j = 0; j < var_count; j++,v++) {
            support_vector[j] += (-myalpha) * (*v);
          }
        }
        support_vector.push_back(rho);
    }
    
    0 讨论(0)
  • 2020-11-30 07:55

    From what I read in Dalal's paper about HOG detector, he suggest that to remove false positives, we need to retrain our model. Retraining is done by applying preliminary model (your model which gives lot of false positives), then detect objects in all negative sample images. All of returned rectangles would definitely false positives.

    Then, add all of these false positives to your negative sample images (negative dataset), do training once again. The resulting model, as suggested in the paper, will return much less false positives.

    Unfortunately though, I tried that (re-training), but the resulting model just does not recognize anything, even on positive image samples. But I think it is worth a try because that was what suggested in the inventor's paper about HOG detector

    0 讨论(0)
提交回复
热议问题