【问题标题】:Error while trying to train SVM (cannot initialize label correctly)尝试训练 SVM 时出错(无法正确初始化标签)
【发布时间】:2015-08-10 06:26:55
【问题描述】:

我正在尝试使用 4 张图像训练我的 svm。我所有的图像都是 300*400。我将它们的大小调整为 304*400,因此由于 16*16 块,我可以获得图像的 HOGDescriptor。然后我使用 Core.hconcat(mats, trainData) 将我所有的图像收集到一个 Mat 中。之后,当我尝试为我的 trainData 设置标签时,在火车部分我得到低于错误。我是openCV的新手。怎么了?

    Mat rose1 = new Mat();
    Mat rose2 = new Mat();
    Mat rose3 = new Mat();
    Mat rose4 = new Mat();
    Mat rose5 = new Mat();

    try {
        rose1 = org.opencv.android.Utils.loadResource(
                getApplicationContext(), R.drawable.rose1);
        rose2 = org.opencv.android.Utils.loadResource(
                getApplicationContext(), R.drawable.rose2);
        rose3 = org.opencv.android.Utils.loadResource(
                getApplicationContext(), R.drawable.rose3);
        rose4 = org.opencv.android.Utils.loadResource(
                getApplicationContext(), R.drawable.rose4);
        rose5 = org.opencv.android.Utils.loadResource(
                getApplicationContext(), R.drawable.rose5);
    } catch (IOException e) {
        e.printStackTrace();
    }

    Mat rose1Resized = new Mat();
    Mat rose2Resized = new Mat();
    Mat rose3Resized = new Mat();
    Mat rose4Resized = new Mat();

    Size sz = new Size(304, 400);

    Imgproc.resize(rose1, rose1Resized, sz);
    Imgproc.resize(rose2, rose2Resized, sz);
    Imgproc.resize(rose3, rose3Resized, sz);
    Imgproc.resize(rose4, rose4Resized, sz);

    // HOG
    MatOfFloat rose1Float = new MatOfFloat();
    MatOfFloat rose2Float = new MatOfFloat();
    MatOfFloat rose3Float = new MatOfFloat();
    MatOfFloat rose4Float = new MatOfFloat();

    HOGDescriptor hog = new HOGDescriptor(new Size(304, 400), new Size(16,
            16), new Size(new Point(8, 8)), new Size(new Point(8, 8)), 9);
    hog.compute(rose1Resized, rose1Float);
    hog.compute(rose2Resized, rose2Float);
    hog.compute(rose3Resized, rose3Float);
    hog.compute(rose4Resized, rose4Float);

    ArrayList<Mat> mats = new ArrayList<>();
    mats.add(rose1Float);
    mats.add(rose2Float);
    mats.add(rose3Float);
    mats.add(rose4Float);

    // SVM
    Mat trainData = new Mat();
    Core.hconcat(mats, trainData);

    float[] lableFloat = { 1, 1, 1, 1 };
    Mat lables = new Mat(1, 4, CvType.CV_32FC1);
    lables.put(0, 0, lableFloat);

    CvSVM svm = new CvSVM();
    CvSVMParams params = new CvSVMParams();
    params.set_svm_type(CvSVM.C_SVC);
    params.set_kernel_type(CvSVM.LINEAR);
    params.set_term_crit(new TermCriteria(TermCriteria.EPS, 100, 1e-6));

    svm.train(trainData, lables, new Mat(), new Mat(), params);

错误是: E/AndroidRuntime(27347): CvException [org.opencv.core.CvException: cv::Exception: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/ml/src/inner_functions.cpp:671: 错误: (-209) 响应数组必须包含与函数 cvPreprocessCategoricalResponses 中样本总数一样多的元素

【问题讨论】:

  • 试试:Mat lables = new Mat(4, 1, CvType.CV_32FC1);。另外,如果你想做分类而不是回归,你需要整数标签,而不是浮点标签。
  • @berak 我把它改成了 int[] lableFloat = { 1, 1, 1, 1 };标签 = new Mat(4, 1, CvType.CV_32SC1);还是一样的错误...
  • 看看`Core.hconcat(mats, trainData);`的结果,trainData也需要正好有4行。
  • 与其使用 hconcat 和您的 ArayList,不如使用 trainData.push_back(rose1Float); trainData.push_back(rose2Float); 等。下一个问题是:你只有一个类标签(1),你至少需要 2 个不同的标签。
  • @berak exactyyy ...首先,在我从 MatOfFloats 得到 hog 之后,我使用了 reshape(1,1)。因为rose1Float 是 65268*1,它应该是 1*65268。在那之后,正如你所说,我使用了 push_back,然后我遇到了一个问题,即我只有一个标签,正如你所说的那样。十分感谢。它现在工作得很好。

标签: android opencv svm


【解决方案1】:

首先我在得到 HOG 之后重塑了 MatOfFloat。因为rose1Float 是65268*1,我需要它在一行Mat.

    Mat roseReshaped1 = rose1Float.reshape(1, 1);
    Mat roseReshaped2 = rose2Float.reshape(1, 1);
    Mat roseReshaped3 = rose3Float.reshape(1, 1);
    Mat roseReshaped4 = rose4Float.reshape(1, 1);

然后我使用 push_back 而不是“Core.hconcat(mats, trainData)”

    Mat trainData = new Mat(0, sizeOfCols, CvType.CV_32FC1);
    trainData.push_back(roseReshaped1);
    trainData.push_back(roseReshaped2);
    trainData.push_back(roseReshaped3);
    trainData.push_back(roseReshaped4);

我的 trainData 将是 4*65268,这是我的标签。或者正如opencv所说,响应!

    int[] l = { 1, 2, 3, 4 };
    Mat lables = new Mat(4, 1, CvType.CV_32SC1);
    lables.put(0, 0, l);

现在一切正常。感谢@berak。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 2021-05-19
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 2015-06-12
    相关资源
    最近更新 更多