2014-08-28 106 views
1

我想檢測給定的圖像上的笑容,但我得到一個錯誤的參數錯誤:Java的OpenCV的訓練SVM錯誤 - 輸入樣本必須是1維向量

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的最後一行(墊面) 方法。整個代碼:

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)); 
} 
} 

我只使用一個訓練圖像樣本,但稍後我會重寫它。現在我只想做預測工作。

回答

2

reshape回報另一墊,這是行不通的就地

所以,你的代碼更改爲:

out = out.reshape(1, 1); 

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

(不用擔心,如果我有一分錢給大家,誰進入那個坑,我會很有錢)

+0

那麼,當我改變你的線我得到:樣本大小是不同於已用於訓練功能cvPreparePredictData – 2014-08-28 19:08:40

+4

所有圖像(用於訓練&預測)必須是相同的大小 – berak 2014-08-28 19:23:19