我正在尝试训练自己的探测器与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()使用原始支持向量进行分类,因此我计算原始形式的方式可能有问题.
是否有人训练过他们自己的探测器谁能指出我正确的方向?
在线性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)