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

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

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

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

 out = out.reshape(1, 1); 

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

(没有恐惧,如果我给每个人一分钱,谁进入那个坑,我会变得富有)