问题描述
我正在尝试训练我自己的检测器以与 OpenCV::HOGDescriptor 一起使用,但是我无法让现有的 HOGDescriptor 与我新训练的 SVM 一起使用.
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.
我计算了正负训练图像的 HOG 特征,标记它们并使用 CvSVM 训练 SVM.我使用的参数是:
I have calculated HOG features for positive and negative training images, labeled them and trained the SVM using CvSVM. The parameters I have used are:
CvSVMParams params;
params.svm_type =CvSVM::EPS_SVR;
params.kernel_type = CvSVM::LINEAR;
params.C = 0.01;
params.p = 0.5;
然后我计算支持向量的原始形式,以便我只得到一个向量而不是多个向量,并使用 HOGDescriptor.setSVMDetector(vector) 设置计算的支持向量;
Then I calculate Primal Form of the support vectors so that I only get one vector instead of many and set the calculated support vector using HOGDescriptor.setSVMDetector(vector);
这是原始形式
当我使用 CvSVM.predict() 时,我能够使用 SVM 正确地对对象进行分类,但是 HOGDescriptor.detect() 或 detectMultiScale() 总是返回大量正匹配并且没有给出准确的预测.
When I use CvSVM.predict() I am able to correctly classify objects with the SVM, but HOGDescriptor.detect() or detectMultiScale() always returns a lot of positive matches and does not give accurate predictions.
CvSVM.predict() 使用原始支持向量进行分类,因此我计算原始形式的方式可能有问题.
CvSVM.predict() uses the original support vectors for classification so there might be something wrong with the way I'm calculating primal form.
有没有人训练过自己的探测器,可以为我指明正确的方向?
Is there anyone who has trained their own detector who can point me in the right direction?
推荐答案
我写了一个 CvSVM 的子类来在训练线性 svm 后提取原始形式.正样本标记为 1,负样本标记为 -1.奇怪的是,为了从 HogDescriptor 获得正确的结果,我必须在 alphas 前面加上负号并保持 rho 的符号不变.
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.
线性支持向量机.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
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);
}
这篇关于训练自定义 SVM 以在 OpenCV 中与 HOGDescriptor 一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!