训练 SVM 并使用 OpenCV 3.0 保存它

Posted

技术标签:

【中文标题】训练 SVM 并使用 OpenCV 3.0 保存它【英文标题】:Train SVM and save it with OpenCV 3.0 【发布时间】:2016-01-22 16:48:56 【问题描述】:

我正在使用带有 OpenCV 3.0 的 Visual Studio 2010。我正在尝试训练 SVM 并将其保存到文件中,但我遇到了问题。

我的目的是提取一些图像的 HOG 特征并用它们训练一个 SVM。一切似乎都是正确的,但是当我尝试将模型保存在 xml 文件中时,我收到以下错误:

TrainSVM.exe 中 0x000007fefd9bb16d (KernelBase.dll) 中未处理的异常:MICROSOFT C++ 异常:内存位置 0x0026e1b0 处的 cv::Exception。

然后在控制台中显示:

OpenCV Error: Parsing error (SVM模型数据无效,检查sv_count, var_* an d class_count 标签)在 cv::ml::SVMImpl::write,文件 C:\builds\master_PackSlave-w in64-vc12-shared\opencv\modules\ml\src\svm.cpp,第 2027 行

错误似乎出现在SVM没有被正确训练的时候,但是我不明白我在哪里失败了,因为这条线

svm->train(auxResult)

结果为“真”。

我已经检查了图像并且它们已正确加载,有人可以帮助我吗?

提前致谢。

代码如下:

    String imagesPathPos = "Positivas/*.jpg"; // it has filters, too !
    vector<String> fp;
    glob(imagesPathPos, fp); 
    int tamaño = fp.size();

    std::vector<cv::Point> positions;
    positions.push_back(cv::Point(0,0));
    std::vector<float> descriptor;
    Ptr<TrainData> auxResult;

    for (size_t i=0; i<fp.size(); ++i)
    
        string nameFile = fp[i];
        Mat img = imread(fp[i]);     
        cv::Mat grayImg;
        cvtColor( img, grayImg, COLOR_BGR2GRAY );           

        hog.compute(grayImg,descriptor,winStride,trainingPadding,positions);

        Mat auxDescriptor = cv::Mat(descriptor);
        Mat descriptorMat(1,auxDescriptor.rows,CV_32FC1);
        transpose(auxDescriptor, descriptorMat);
        trainingData.push_back(descriptorMat);          
        trainingLabels.push_back(labelPositive);        
    

    String imagesPathNeg = "Negativas/*.jpg";
    vector<String> fn;
    glob(imagesPathNeg, fn, true); 
    for (size_t i=0; i<fn.size(); i++)
    
        Mat img = imread(fn[i]);
        cv::Mat grayImg;
        cvtColor( img, grayImg, COLOR_BGR2GRAY );
        hog.compute(grayImg,descriptor,Size(),Size(),positions);

        Mat auxDescriptor = cv::Mat(descriptor);
        Mat descriptorMat(1,auxDescriptor.rows,CV_32FC1);
        transpose(auxDescriptor, descriptorMat);
        trainingData.push_back(descriptorMat);
        trainingLabels.push_back(labelPositive);
    

    auxResult = TrainData::create(trainingData, type, trainingLabels);

    svm->train(auxResult);

    svm->save("output.xml");

【问题讨论】:

@Noripsni 我看到你发布了here 一个类似的错误,你解决了吗? 【参考方案1】:

即使图像是负面的,您也在定义“labelPositive”。可能存在错误,在通过向量 fn 的循环内:

trainingLabels.push_back(labelPositive);

您应该使用一个名为“labelNegative”的参数,定义为 -1。

【讨论】:

以上是关于训练 SVM 并使用 OpenCV 3.0 保存它的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 线性 SVM 未训练

OpenCV 3.0 svm 总是预测 0 (java)

OpenCVopencv3.0中的SVM训练 mnist 手写字体识别

训练自定义 SVM 以在 OpenCV 中与 HOGDescriptor 一起使用

在 OpencV 中训练 SVM 分类器?

OpenCV for Android - 使用 SURF 描述符训练 SVM