如何使用C++在opencv中训练我自己的svm

How train my own svm in opencv using C++?

本文关键字:我自己 自己的 svm 何使用 C++ opencv      更新时间:2023-10-16

我想用从图像中提取的特征来训练我自己的SVM,所以我从包含人员的图像序列(720x576)中提取特征。我想使用 svm 对检测到的对象进行分类,例如人或其他对象。我的一个特点.dat:

    [-0.00011304629, -0.0012236957, 0.00027119479, 0.0012647118, -0.0018265223, -0.018638615, 0.0098637585, 0.020142596, -0.0012514826, -0.0067296866, 0.0043024337, 0.0080097318, 0.0011584486, -0.00077929819, 0.0013905426, 0.00095518644, 0.0017369018, 0.0079498151, 0.0018530694, 0.0085842144, 0.15540655, 0.23714867, 0.15860459, 0.23714867, -0.028113011, 0.25352797, 0.268282, 0.279008, -0.037383422, 0.02249903, 0.042661294, 0.02340897, 0.0013400698, 0.0048319609, 0.0021884302, 0.0056850719, 0.37904194, -0.066282742, 0.41964364, 0.080511056, -0.23055254, 0.010807713, 0.46629098, 0.049539972, -0.041018508, 0.0058587855, 0.045177955, 0.0067843986, -0.00016448426, 0.0008450991, 0.0019716914, 0.0026907444, 0.053080089, -0.0070953579, 0.057075631, 0.0085162139, -0.03202837, 0.0012674005, 0.053649519, 0.0080802822, 9.4343457e-05, 0.00010923775, 0.0083377175, 0.0015355083;
  -0.0024956728, -0.0024603403, 0.0044404925, 0.0040253471, 0.055309348, 0.006694437, 0.058669563, 0.008123802, -0.031681322, -0.0028714964, 0.056370165, 0.0060769469, -0.0010096794, 6.9015719e-06, 0.0067517483, 0.0011420506, 0.001166827, -0.00068250211, 0.0015904121, 0.0022194763, 0.37670693, 0.056508597, 0.40771538, 0.065799005, -0.22081745, -0.017952221, 0.47782964, 0.051509246, -0.037203062, -0.0030379333, 0.038590115, 0.0047737048, 0.0011766918, -0.01367875, 0.001783903, 0.014545292, 0.15056053, -0.25023517, 0.16026139, 0.25364164, -0.065814815, -0.27434519, 0.20718332, 0.29574585, -0.016427297, -0.033821814, 0.023312433, 0.034270149, -4.2133952e-06, 0.0015094492, 0.00026528162, 0.0015094492, 0.0021759982, 0.021547779, 0.0083950981, 0.021547779, -0.0033076329, 0.015553456, 0.0094896331, 0.015718656, -6.9612266e-05, 0.00065918162, 0.0017252946, 0.0017238797;

您需要先将图像数组更改为行矩阵。

Mat img_mat = imread(imgname,0); // I used 0 for greyscale
int ii = 0; // Current column in training_mat
for (int i = 0; i<img_mat.rows; i++) {
    for (int j = 0; j < img_mat.cols; j++) {
        training_mat.at<float>(file_num,ii++) = img_mat.at<uchar>(i,j);
    }
}

CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::POLY;
params.gamma = 3;
CvSVM svm;
svm.train(training_mat, labels, Mat(), Mat(), params);
svm.predict(img_mat_1d);

此外,图像比例相当大(720 * 576 = 414720)。在训练模型之前,可以进行一些预处理。例如,使用 PCA 减小维度。有关更多详细信息,请参阅将OpenCV和SVM与图像一起使用

我写了这个程序:

 #include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <fstream>


using namespace std;
using namespace cv;

//const float kRescaleFactor = 1.5;
//! main program 
int main(int argc, char* argv[])
{
    ofstream myfile;
    myfile.open("features.dat");
    String folder = "PETS2006/input/*.jpg";
        vector<String> filenames;
        glob(folder, filenames);

    Mat gray;


    int num_files=filenames.size();
    int img_area=720*576;
    Mat training_mat(num_files,img_area,CV_32FC1);
    Mat labels=Mat::ones(num_files,1,CV_32FC1);
    for (size_t i = 0; i <filenames.size(); ++i){
        Mat img=imread(filenames[i]);
        cvtColor(img,gray, CV_RGB2GRAY);

        int ii = 0; // Current column in training_mat
        for (int k = 0; i<gray.rows; i++) {
            for (int j = 0; j < gray.cols; j++) {
            training_mat.at<float>(i,ii++) = gray.at<uchar>(i,j);
            }
        }


    }
        CvSVMParams params;
    params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::POLY;
    params.gamma = 3;
    CvSVM svm;
    svm.train(training_mat, labels, Mat(), Mat(), params);
     svm.save("svm_filename");
    return 0;
}

我收到此错误:

assertion failed DataType<_Tp>one of the arguments values is out of range (The kernel parameter <degree> must be positive in CVSVM::set_params