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 ) );
}
}
I am using Java 8 and OpenCV 2.4.10
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: