【问题标题】:Java OpenCV training SVM error - Input sample must be 1-dimensional vectorJava OpenCV 训练 SVM 错误 - 输入样本必须是一维向量
【发布时间】:2014-10-22 17:09:03
【问题描述】:

我想检测给定图像上的微笑,但我得到一个错误的参数错误:

OpenCV Error: Incorrect size of input array (Input sample must be 1-dimensional vector) in cvPreparePredictData, file ..\..\..\..\opencv\modules\ml\src\inner_functions.cpp, line 1107
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception:    ..\..\..\..\opencv\modules\ml\src\inner_functions.cpp:1107: error: (-201) Input sample must be 1-dimensional vector in function cvPreparePredictData
]

在detectSmile(Mat face) 方法的最后一行。整个代码:

public class SmileDetector {
private CascadeClassifier faceDetector;
private Mat image;
private Mat classes;
private Mat trainingData;
private Mat trainingImages;
private Mat trainingLabels;
CvSVM clasificador;


public void detectSmile(String filename) {
    init();
    detectFace(filename);
    Mat face = Highgui.imread("output.png", Highgui.CV_LOAD_IMAGE_GRAYSCALE);
    detectSmile(face);
}

private void init() {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    faceDetector = new CascadeClassifier(new File(
            "src/main/resources/haarcascade_frontalface_alt.xml").getAbsolutePath());
    classes = new Mat();
    trainingData = new Mat();
    trainingImages = new Mat();
    trainingLabels = new Mat();
}

private void detectFace(String filename) {
    image = Highgui.imread(filename);
    MatOfRect faceDetections = new MatOfRect();
    faceDetector.detectMultiScale(image, faceDetections);
    System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
    for (Rect rect : faceDetections.toArray()) {
        Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(0, 255, 0));
    }
    Highgui.imwrite("output.png", image.submat(faceDetections.toArray()[0]));
}

private void trainSVM() {
    trainPositive();
    trainNegative();
    trainingImages.copyTo(trainingData);
    trainingData.convertTo(trainingData, CvType.CV_32FC1);
    trainingLabels.copyTo(classes);
}

private void trainPositive() {
    Mat img = new Mat();
    Mat con = Highgui.imread("D:\\cybuch\\workspace\\facerecognizer\\src\\main\\resources\\happy.png", Highgui.CV_LOAD_IMAGE_GRAYSCALE);
    con.convertTo(img, CvType.CV_32FC1,1.0/255.0);
    trainingImages.push_back(img.reshape(1, 1));
    trainingLabels.push_back(Mat.ones(new Size(1, 1), CvType.CV_32FC1));
}

private void trainNegative() {
    Mat img = new Mat();
    Mat con = Highgui.imread("D:\\cybuch\\workspace\\facerecognizer\\src\\main\\resources\\sad.png", Highgui.CV_LOAD_IMAGE_GRAYSCALE);
    con.convertTo(img, CvType.CV_32FC1,1.0/255.0);
    trainingImages.push_back(img.reshape(1,1));
    trainingLabels.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32FC1));   
}

private void detectSmile(Mat face) {
    trainSVM();
    CvSVMParams params = new CvSVMParams();
    params.set_kernel_type(CvSVM.LINEAR);
    clasificador = new CvSVM(trainingData, classes, new Mat(), new Mat(), params);  
    clasificador.save("svm.xml");
    clasificador.load("svm.xml");
    System.out.println(clasificador);
    Mat out = new Mat();
    face.convertTo(out, CvType.CV_32FC1);
    out.reshape(1, 1);
    System.out.println(out);
    System.out.println(clasificador.predict(out));
}
}

我只使用了一个训练图像样本,但我稍后会重写它。现在我只想让预测工作。

【问题讨论】:

    标签: java opencv


    【解决方案1】:

    reshape 返回另一个 Mat,它不能就地工作

    所以,将您的代码更改为:

    out = out.reshape(1, 1);
    

    ( 或 clasificador.predict(out.reshape(1,1)) )

    (不用担心,如果我为每个踏入那个坑的人都分得一分钱,我会很富有)

    【讨论】:

    • 好吧,当我为你换行时,我得到:样本量与函数 cvPreparePredictData 中用于训练的样本量不同
    • 所有图像(用于训练和预测)的大小必须相同
    猜你喜欢
    • 1970-01-01
    • 2015-02-07
    • 2015-05-04
    • 2015-07-25
    • 2016-06-25
    • 2015-04-18
    • 2015-01-22
    • 2013-04-20
    相关资源
    最近更新 更多