Hello all, I am new to openCV and trying to learn how to write an image recognition application in java. Samples have been tough to find but I am scouring the web. I found an example to train images and create a data file. But even though it compiles it fails on one particular line. Here is the whole source code:
import java.io.File;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.ml.CvSVM;
import org.opencv.ml.CvSVMParams;
public class TrainOpenCV {
protected static final String PATH_POSITIVE = "data/positive/";
protected static final String PATH_NEGATIVE = "data/negative/";
protected static final String XML = "data/test.xml";
protected static final String FILE_TEST = "data/negative/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 );
System.out.println("c");
// **** The line below is where it breaks ****
clasificador = new CvSVM(trainingData, classes, new Mat(), new Mat(), params );
System.out.println("d");
clasificador.save( XML );
}
protected static void trainPositive() {
for ( File file : new File( PATH_POSITIVE ).listFiles() ) {
Mat img = getMat( file.getAbsolutePath() );
System.out.println("img = "+ img.empty() + img.height());
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;
}
}
When it hits the line "clasificador = new CvSVM(trainingData, classes, new Mat(), new Mat(), params );" I get the following error:
"OpenCV Error: Bad argument (There is only a single class) in cvPreprocessCategoricalResponses, file ........\opencv\modules\ml\src\inner_functions.cpp, line 729 Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: ........\opencv\modules\ml\src\inner_functions.cpp:729: error: (-5) There is only a single class in function cvPreprocessCategoricalResponses ] at org.opencv.ml.CvSVM.CvSVM_1(Native Method) at org.opencv.ml.CvSVM.<init>(CvSVM.java:90) at TrainOpenCV.train(TrainOpenCV.java:71) at TrainOpenCV.main(TrainOpenCV.java:35)"
I appreciate any help!