在OpenCV中训练自定义SVM以与HOGDescriptor一起使用

Jom*_*234 4 c++ opencv svm

我正在尝试训练自己的探测器与OpenCV :: HOGDescriptor一起使用,但我无法使现有的HOGDescriptor与我新训练的SVM一起工作.

我已经为正面和负面训练图像计算了HOG特征,标记了它们并使用CvSVM训练了SVM.我使用的参数是:

    CvSVMParams params;
    params.svm_type =CvSVM::EPS_SVR;
    params.kernel_type = CvSVM::LINEAR;
    params.C = 0.01;
    params.p = 0.5;
Run Code Online (Sandbox Code Playgroud)

然后我计算支持向量的原始形式,这样我只得到一个向量而不是多个向量,并使用HOGDescriptor.setSVMDetector(向量)设置计算的支持向量;

这是原始形式

当我使用CvSVM.predict()时,我能够使用SVM正确地对对象进行分类,但是HOGDescriptor.detect()或detectMultiScale()总是返回许多正匹配,并且不能给出准确的预测.

CvSVM.predict()使用原始支持向量进行分类,因此我计算原始形式的方式可能有问题.

是否有人训练过他们自己的探测器谁能指出我正确的方向?

DXM*_*DXM 5

在线性svm训练之后,我编写了一个CvSVM的子类来提取原始形式.阳性样品标记为1,阴性样品标记为-1.奇怪的是,我必须在alphas前加上负号,并保持rho的符号不变,以便从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_ */
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)