C++ OpenCV 3.4.1获取自定义训练线性SVM的原始形式多尺度

C++ OpenCV 3.4.1获取自定义训练线性SVM的原始形式多尺度,c++,linux,opencv,opencv3.1,opencv3.3,C++,Linux,Opencv,Opencv3.1,Opencv3.3,我在OpenCV 3.4.1中训练了一个线性支持向量机。现在我想将我的自定义SVM与OpenCV 3的HoG detectMultiScale函数一起使用。使用自定义SVM原始向量设置HoG检测器的旧方法不再有效 对于OpenCV 2,可以从OpenCV 2自定义训练的SVM中获得原始向量,如下所示: #include "linearsvm.h" LinearSVM::LinearSVM() { qDebug() << "Creating SVM and loading

我在OpenCV 3.4.1中训练了一个线性支持向量机。现在我想将我的自定义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;
}
    // 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);
// 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;
/// Get the SVM Detector in HoG Format
vector<float> getSVMDetector(const Ptr<SVM>& svm)
{
    // get the support vectors
    Mat sv = svm->getSupportVectors();
    const int sv_total = sv.rows;
    // get the decision function
    Mat alpha, svidx;
    double rho = svm->getDecisionFunction( 0, alpha, svidx );

    CV_Assert( alpha.total() == 1 && svidx.total() == 1 && sv_total == 1 );
    CV_Assert( (alpha.type() == CV_64F && alpha.at<double>(0) == 1.) ||
               (alpha.type() == CV_32F && alpha.at<float>(0) == 1.f) );
    CV_Assert( sv.type() == CV_32F );

    vector< float > hog_detector( sv.cols + 1 );
    memcpy( &hog_detector[0], sv.ptr(), sv.cols*sizeof( hog_detector[0] ) );
    hog_detector[sv.cols] = (float)-rho;
    return hog_detector;
}
#包括“linearsvm.h”
LinearSVM::LinearSVM(){

qDebug()事实证明答案在Github上的OpenCV测试/示例train_HOG.cpp中

看起来是这样的:

#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;
}
    // 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);
// 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;
/// Get the SVM Detector in HoG Format
vector<float> getSVMDetector(const Ptr<SVM>& svm)
{
    // get the support vectors
    Mat sv = svm->getSupportVectors();
    const int sv_total = sv.rows;
    // get the decision function
    Mat alpha, svidx;
    double rho = svm->getDecisionFunction( 0, alpha, svidx );

    CV_Assert( alpha.total() == 1 && svidx.total() == 1 && sv_total == 1 );
    CV_Assert( (alpha.type() == CV_64F && alpha.at<double>(0) == 1.) ||
               (alpha.type() == CV_32F && alpha.at<float>(0) == 1.f) );
    CV_Assert( sv.type() == CV_32F );

    vector< float > hog_detector( sv.cols + 1 );
    memcpy( &hog_detector[0], sv.ptr(), sv.cols*sizeof( hog_detector[0] ) );
    hog_detector[sv.cols] = (float)-rho;
    return hog_detector;
}
///以HoG格式获取SVM检测器
向量getSVMDetector(常量Ptr和svm)
{
//获取支持向量
Mat sv=svm->getSupportVectors();
const int sv_total=sv.rows;
//得到决策函数
Mat-alpha,svidx;
双rho=svm->getDecisionFunction(0,alpha,svidx);
CV_断言(alpha.total()==1&&svidx.total()==1&&sv_total==1);
CV_断言((alpha.type()==CV_64F&&alpha.at(0)==1。)||
(alpha.type()==CV_32F&&alpha.at(0)==1.f));
CV_断言(sv.type()==CV_32F);
向量hog_检测器(sv.cols+1);
memcpy(&hog_检测器[0],sv.ptr(),sv.cols*sizeof(hog_检测器[0]);
hog_检测器[sv.cols]=(浮点数)-rho;
返回式hog_检测器;
}