java中的Opencv SVM无法正确训练

时间:2018-03-03 11:50:16

标签: java android opencv svm opencv4android

请帮帮我。我正在尝试创建Android应用以检测​​答案纸中的冒泡答案。我正在使用Opencv 3.4并面临问题:OPENCV SVM是不正确的训练,因为训练持续时间非常小(几秒)。这是我的代码:

    private static Mat trainingMat;
private static Mat trainingLabels;
private static SVM clasificador;
private static int img_area = 50 * 70;
private static int negativo_size = 520;
private static int positivo_size = 349;
private static int file_count = 0;

public static void main(String[] args) {
    System.load("E:/Android/opencv/build/java/x64/opencv_java340.dll");
    trainingMat = new Mat(negativo_size + positivo_size, img_area, CvType.CV_32FC1);
    trainingLabels = new Mat(negativo_size + positivo_size, 1, CvType.CV_32S);
    trainingLabels = new Mat();
    clasificador = SVM.create();
    trainPositive();
    trainNegative();
    train();
    test();
}


private static void test() {
    SVM svm = SVM.load(new File(XML).getAbsolutePath());
    Mat in = getMat(FILE_TEST);
    in.reshape(1);
    Mat out = new Mat(1, img_area, CvType.CV_32FC1);
    int ii = 0;
    for (int i = 0; i < in.rows(); i++) {
        for (int j = 0; j < in.cols(); j++) {
            out.put(1, ii, in.get(i, j));
            ii++;
        }
    }
    System.out.println("prediction is:" + svm.predict(out));
}

private static void train() {
    clasificador.setType(SVM.C_SVC);
    clasificador.setKernel(SVM.POLY);
    clasificador.setGamma(3);
    clasificador.setDegree(3);
    clasificador.train(trainingMat, Ml.ROW_SAMPLE, trainingLabels);
    clasificador.save(XML);
}

private static void trainPositive() {
    for (File file : new File(PATH_POSITIVE).listFiles()) {
        Mat img = getMat(file.getAbsolutePath());
        img.reshape(1);
        int ii = 0;
        for (int i = 0; i < img.rows(); i++) {
            for (int j = 0; j < img.cols(); j++) {
                trainingMat.put(file_count, ii, img.get(i, j));
                ii++;
            }
        }
        file_count++;
    }
}

private static void trainNegative() {
    for (File file : new File(PATH_NEGATIVE).listFiles()) {
        Mat img = getMat(file.getAbsolutePath());
        img.reshape(1);
        int ii = 0;
        for (int i = 0; i < img.rows(); i++) {
            for (int j = 0; j < img.cols(); j++) {
                trainingMat.put(file_count, ii, img.get(i, j));
                ii++;
            }
        }
        file_count++;
    }
    trainingLabels.rowRange(0,positivo_size-1).setTo(new Scalar(1.0));
    trainingLabels.rowRange(positivo_size,positivo_size+negativo_size -1).setTo(new Scalar(-1.0));
}

private static Mat getMat(String path) {
    Mat img = new Mat();
    Mat con = Imgcodecs.imread(path, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
    con.convertTo(img, CvType.CV_32FC1, 1.0 / 255.0);
    return img;
}

当我编译此代码时,SVM预测总是返回1.0。怎么了? 更多细节: Opencv 3.4版 输入图像尺寸50 * 70 否定图像计数= 520 正像数= 349;

1 个答案:

答案 0 :(得分:0)

只需检查SVM是否受过训练。您可以使用svm.trained(); 如果在train()之后未对svm进行训练,则它将返回一个布尔值,它将始终预测100%的准确性。在不知道项目和数据集的情况下找到解决方案是不可能的。我的建议是检查数据集以及如何准备将其插入svm。