Java + OpenCV SVM培训错误 [英] Java + OpenCV SVM Training Error

查看:77
本文介绍了Java + OpenCV SVM培训错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试训练一组图像以生成训练文件,然后识别图像中的某些对象,将其设置为可以训练的正负集分开设置即可.

I'm trying to train a set of images to generate a training file and then identify some objects in images, separated set a positive and a negative set it up can train.

当我使用已经训练过的文件进行测试时,会出现问题,因为它返回一个错误,指出输入文件的大小与训练样本的大小不同.但这是没有道理的,因为已经训练了相同的图像.

The problem occurs when I do the test with a file that was already trained, because it returns an error saying that the size of the input file is different from the size of the training sample. But that does not make sense, because the same image has already been trained.

public class Training{

protected static final String PATH_POSITIVE = "data/positivo/";
protected static final String PATH_NEGATIVE = "data/negativo/";
protected static final String XML = "data/test.xml";
protected static final String FILE_TEST = "data/positivo/1.jpg";

static {
    System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
}

protected static Mat getMat( Mat img ) {
    Mat timg = new Mat();
    Imgproc.cvtColor( img, timg, Imgproc.COLOR_BGR2GRAY );
    timg = timg.reshape( 1, timg.width() * timg.height() );
    timg.convertTo( timg, CvType.CV_32FC1 );
    return timg;
}

public static void main( String[ ] args ) {

    Mat classes = new Mat();
    Mat trainingData = new Mat();

    Mat trainingImages = new Mat();
    Mat trainingLabels = new Mat();

    CvSVM clasificador;

    for ( File file : new File( PATH_POSITIVE ).listFiles() ) {
        Mat img = Highgui.imread( file.getAbsolutePath() );
        trainingImages.push_back( getMat( img ) );
        trainingLabels.push_back( Mat.ones( new Size( 1, img.width() * img.height() ), CvType.CV_32FC1 ) );
    }

    for ( File file : new File( PATH_NEGATIVE ).listFiles() ) {
        Mat img = Highgui.imread( file.getAbsolutePath() );
        trainingImages.push_back( getMat( img ) );
        trainingLabels.push_back( Mat.zeros( new Size( 1, img.width() * img.height() ), CvType.CV_32FC1 ) );
    }

    trainingImages.copyTo( trainingData );
    trainingData.convertTo( trainingData, CvType.CV_32FC1 );
    trainingLabels.copyTo( classes );

    CvSVMParams params = new CvSVMParams();
    params.set_kernel_type( CvSVM.LINEAR );
    params.set_svm_type( CvSVM.C_SVC );
    params.set_gamma( 3 );

    clasificador = new CvSVM( trainingData, classes, new Mat(), new Mat(), params );
    clasificador.train( trainingData, classes );
    clasificador.save( XML );

    //Finished the part of the training will run the test with any file

    clasificador = new CvSVM();
    clasificador.load( new File( XML ).getAbsolutePath() );
    Mat timg = getMat( Highgui.imread( new File( FILE_TEST ).getAbsolutePath() ) );
    timg = timg.reshape( 1, timg.width() * timg.height() );
    timg.convertTo( timg, CvType.CV_32FC1 );

    //Here the error occurs
    //Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: ..\..\..\..\opencv\modules\ml\src\inner_functions.cpp:1114: error: (-209) The sample size is different from what has been used for training in function cvPreparePredictData
    System.out.println( clasificador.predict( timg ) );

}

}

我正在使用Java 8和OpenCV 2.4.10

I am using Java 8 and OpenCV 2.4.10

推荐答案

基于@berak给出的注释,我决定对原始代码进行一些更改.结果是以下代码,它对我有用:

Based on the comments given by @berak, I decided to make some changes to my original code. The result is the following code and it is working for me:

public class Training{

protected static final String PATH_POSITIVE = "data/positivo/";
protected static final String PATH_NEGATIVE = "data/negativo/";
protected static final String XML = "data/test.xml";
protected static final String FILE_TEST = "data/negativo/1.jpg";

private static Mat trainingImages;
private static Mat trainingLabels;
private static Mat trainingData;
private static Mat classes;
private static CvSVM clasificador;

static {
    System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
    trainingImages = new Mat();
    trainingLabels = new Mat();
    trainingData = new Mat();
    classes = new Mat();
}

public static void main( String[ ] args ) {
    trainPositive();
    trainNegative();
    train();
    test();
}

protected static void test() {
    Mat in = Highgui.imread( new File( FILE_TEST ).getAbsolutePath(), Highgui.CV_LOAD_IMAGE_GRAYSCALE );
    clasificador.load( new File( XML ).getAbsolutePath() );
    System.out.println( clasificador );
    Mat out = new Mat();
    in.convertTo( out, CvType.CV_32FC1 );
    out = out.reshape( 1, 1 );
    System.out.println( out );
    System.out.println( clasificador.predict( out ) );
}

protected static void train() {
    trainingImages.copyTo( trainingData );
    trainingData.convertTo( trainingData, CvType.CV_32FC1 );
    trainingLabels.copyTo( classes );
    CvSVMParams params = new CvSVMParams();
    params.set_kernel_type( CvSVM.LINEAR );
    clasificador = new CvSVM( trainingData, classes, new Mat(), new Mat(), params );
    clasificador.save( XML );
}

protected static void trainPositive() {
    for ( File file : new File( PATH_POSITIVE ).listFiles() ) {
        Mat img = getMat( file.getAbsolutePath() );
        trainingImages.push_back( img.reshape( 1, 1 ) );
        trainingLabels.push_back( Mat.ones( new Size( 1, 1 ), CvType.CV_32FC1 ) );
    }
}

protected static void trainNegative() {
    for ( File file : new File( PATH_NEGATIVE ).listFiles() ) {
        Mat img = getMat( file.getAbsolutePath() );
        trainingImages.push_back( img.reshape( 1, 1 ) );
        trainingLabels.push_back( Mat.zeros( new Size( 1, 1 ), CvType.CV_32FC1 ) );
    }
}

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

}

这篇关于Java + OpenCV SVM培训错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆