我在 OpenCV 3.4.1 中训练了一个线性 SVM。现在我想将我的自定义 SVM 与 OpenCV 3 的 HoG detectMultiScale 函数一起使用。使用自定义 SVM 原始向量设置 HoG 检测器的旧方法不再有效。
对于 OpenCV 2,可以从 OpenCV 2 自定义训练的 SVM 中获取原始向量,如下所示:
#include "linearsvm.h"
LinearSVM::LinearSVM() {
qDebug() << "Creating SVM and loading trained data...";
load("/home/pi/trainedSVM.xml");
qDebug() << "Done loading data...";
}
std::vector<float> LinearSVM::getPrimalForm() const
{
std::vector<float> support_vector;
int sv_count = get_support_vector_count();
const CvSVMDecisionFunc* df = getDecisionFunction();
if ( !df ) {
return support_vector;
}
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);
return support_vector;
}
从经过训练的 SVM 数据创建原始向量后,可以像这样设置 HoG 检测器 SVM:
// Primal for of cvsvm descriptor
vector<float> primalVector = m_CvSVM.getPrimalForm();
qDebug() << "Got primal form of detection vector...";
qDebug() << "Setting SVM detector...";
// Set the SVM Detector - custom trained HoG Detector
m_HoG.setSVMDetector(primalVector);
在 OpenCV 3.4.1 中,这不再有效,因为 CvSVM 不再存在并且大部分 SVM API 已更改。
如何在 OpenCV 3.4.1 中获得我这样训练的自定义 SVM 的原始向量:
// Set up SVM's parameters
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
svm->setType(cv::ml::SVM::C_SVC);
svm->setKernel(cv::ml::SVM::LINEAR);
svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 10, 1e-6));
// Train the SVM with given parameters
cv::Ptr<cv::ml::TrainData> td = cv::ml::TrainData::create(trainingDataMat, cv::ml::ROW_SAMPLE, trainingLabelsMat);
// Or auto train
qDebug() << "Training dataset...";
QElapsedTimer trainingTimer;
trainingTimer.restart();
svm->trainAuto(td);
qDebug() << "Done training dataset in: " << (float)trainingTimer.elapsed() / 1000.0f;
谢谢。