训练 SVM 时出现 OpenCV 错误(错误参数)

Posted

技术标签:

【中文标题】训练 SVM 时出现 OpenCV 错误(错误参数)【英文标题】:OpenCV error while training SVM (bad argument) 【发布时间】:2015-06-12 17:14:19 【问题描述】:

我创建了带有训练图像的 Mat(150 张图像大小为 144x33),所以我的 Mat 宽度为 4752,高度为 150。另一个带有标签的垫子是 1 宽和 150 高。现在,当我尝试使用这两个 Mat 的 svm.train() 时,出现以下错误:

OpenCV Error: Bad argument (response #2 is not integral) in cvPreprocessCategoricalResponses, file ..\..\..\..\opencv\modules\ml\src\inner_functions.cpp, line 715
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: ..\..\..\..\opencv\modules\ml\src\inner_functions.cpp:715: error: (-5) response #2 is not integral in function cvPreprocessCategoricalResponses]

这是我的一段代码,谁能告诉我哪里出了问题?

Mat trainingImages = new Mat(0, imageWidth * imageHeight, CvType.CV_32FC1);
    Mat labels = new Mat(amountOfPlates + amountOfNoPlates, 1, CvType.CV_32FC1);
    List<Integer> trainingLabels = new ArrayList<>();

    for (int i = 0; i < amountOfPlates; i++) 
        int index = i + 1;
        String file = pathPlates + index + ".jpg";

        Mat img = Highgui.imread(file, 0);
        img.convertTo(img, CvType.CV_32FC1);
        img = img.reshape(1, 1);
        trainingImages.push_back(img);
        trainingLabels.add(1);
    

    for (int i = 0; i < amountOfNoPlates; i++) 
        int index = i + 1;
        String file = pathNoPlates + index + ".jpg";
        Mat img = Highgui.imread(file, 0);
        img.convertTo(img, CvType.CV_32FC1);
        img = img.reshape(1, 1);
        trainingImages.push_back(img);
        trainingLabels.add(0);
    

    Integer[] array = trainingLabels.toArray(new Integer[trainingLabels.size()]);

    int[] trainLabels = new int[array.length];
    for (int i = 0; i < array.length; i++) 
        trainLabels[i] = array[i];
    

    for (int i = 0; i < trainingLabels.size(); i++) 
        labels.put(i, 1, trainLabels[i]);
    

    CvSVMParams params = new CvSVMParams();
    params.set_svm_type(CvSVM.C_SVC);
    params.set_kernel_type(CvSVM.LINEAR);
    params.set_degree(0);
    params.set_gamma(1);
    params.set_coef0(0);
    params.set_C(1);
    params.set_nu(0);
    params.set_p(0);
    TermCriteria tc = new TermCriteria(opencv_core.CV_TERMCRIT_ITER, 1000, 0.01);
    params.set_term_crit(tc);

    Size data = trainingImages.size();
    Size label = labels.size();


    CvSVM svmClassifier = new CvSVM();
    svmClassifier.train(trainingImages, labels, new Mat(), new Mat(), params);
    svmClassifier.save("test.xml");

尺寸数据显示:width = 4752, height = 150

尺寸标签显示:width = 1, height = 150

我做错了什么?

【问题讨论】:

【参考方案1】:

Mat labels 被定义为CV_32FC1,但您使用来自int[] trainLabels 的整数对其进行扩展。 您应该改用浮点 trainLabelsCV_32SC1 类型 labels

【讨论】:

标签 Mat 应该是 CV_32SC1,因为它是一个分类任务,如果你给 svm 一个浮点标签 Mat,它认为,你想要一个回归。 谢谢,它立即有帮助! :) 顺便问一下 CV_32SC1 到底是什么? CV_32SC1 用于有符号整数,这意味着您的矩阵存储ints。

以上是关于训练 SVM 时出现 OpenCV 错误(错误参数)的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV SVM 在火车上抛出异常,“错误参数(只有一个类)”

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

尝试使用 SVM 对数据集进行分类时出现错误 [重复]

使用 R2013b MATLAB 版本时出现 SVM 错误

在 OpencV 中训练 SVM 分类器?

OpenCV 线性 SVM 未训练