opencv3.2.0 java svm train error
my code: import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.ml.Ml; import org.opencv.ml.SVM; import org.opencv.ml.TrainData;
import java.io.File; import java.util.ArrayList; import java.util.List;
import static org.opencv.imgproc.Imgproc.cvtColor; import static org.opencv.imgproc.Imgproc.threshold;
public class SvmTrain { public static final String SVM_MODEL_FILE_PATH = "resources/b_process/svm/model/svm.xml";
public static final String SVM_ROOT = "resources/b_process/svm/";
public static final String SVM_HAS_TEST = "has/test";
public static final String SVM_HAS_TRAIN = "has/train";
public static final String SVM_NO_TEST = "no/test";
public static final String SVM_NO_TRAIN = "no/train";
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
SvmTrain vl = new SvmTrain();
vl.train();
}
void train(){
//初始化SVM
SVM svm = SVM.create();
svm.setType(SVM.C_SVC);
svm.setKernel(SVM.RBF);
svm.setDegree(0.1);
// 1.4 bug fix: old 1.4 ver gamma is 1
svm.setGamma(0.1);
svm.setCoef0(0.1);
svm.setC(1);
svm.setNu(0.1);
svm.setP(0.1);
svm.setTermCriteria(new TermCriteria(1, 20000, 0.0001));
//load data
TrainData trainData = loadTrainData();
//train
long star = System.currentTimeMillis();
System.out.println("start train...");
svm.train(trainData);
System.out.println("end train...total time : " +(System.currentTimeMillis()-star) + "ms");
svm.save(SVM_MODEL_FILE_PATH);
System.out.println("save the train model...");
}
/**
* @return
*/
TrainData loadTrainData() {
List<File> hasFileList = getFiles(SVM_ROOT+SVM_HAS_TRAIN);
List<File> noFileList = getFiles(SVM_ROOT+SVM_NO_TRAIN);
int hasCount = hasFileList.size();
int noCount = noFileList.size();
Mat samples = new Mat();
Mat labels = new Mat();
for (int i = 0; i < hasCount; i++) {//positive
Mat img = getMat(hasFileList.get(i).getAbsolutePath());
samples.push_back( img.reshape( 1, 1 ) );
labels.push_back( Mat.ones( new Size( 1, 1 ), CvType.CV_32FC1 ) );
}
for (int j= 0; j < noCount; j++) {//negative
Mat img = getMat( hasFileList.get(j).getAbsolutePath());
samples.push_back( img.reshape( 1, 1 ) );
labels.push_back( Mat.zeros( new Size( 1, 1 ), CvType.CV_32FC1 ) );
}
Mat trainingData = new Mat();
Mat classes = new Mat();
samples.copyTo(trainingData);
trainingData.convertTo( trainingData, CvType.CV_32FC1 );
labels.copyTo(classes);
return TrainData.create(trainingData , Ml.ROW_SAMPLE,classes);
}
public 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;
}
public Mat getHistogramFeatures(Mat image) {
Mat grayImage = new Mat();
cvtColor(image, grayImage, Imgproc.COLOR_RGB2GRAY);
Mat img_threshold = new Mat();
threshold(grayImage, img_threshold, 0, 255, Imgproc.THRESH_OTSU + Imgproc.THRESH_BINARY);
return img_threshold;
}
/**
* @Param floderPath
* @return
*/
public List<File> getFiles(String floderPath){
List<File> list = new ArrayList<File>();
File file = new File(floderPath);
if (!file.exists()) {
System.out.println("Error : " + floderPath + " folder is not exist!");
return list;
}
if (!file.isDirectory()) {
System.out.println("Error : " + floderPath + " is not a folder!");
return list;
}
File[] files = file.listFiles();
if (files.length == 0) {
System.out.println("Error : " + floderPath + " folder is empty!");
return list;
}
for (int i = 0; i < files.length; i++) {
File f = files[i];
list.add(f);
}
return list;
}
}
run the code ,exception :
Exception in thread "main" java.lang.Exception: unknown exception
at org.opencv.ml.StatModel.train_2(Native Method)
at org ...
@berak My test image 700x100 , 100~150kb~
i debug the program , the code "svm.train(traindata) " erro
Exception in thread "main" java.lang.Exception: unknown exception at org.opencv.ml.StatModel.train_2(Native Method) at org.opencv.ml.StatModel.train(StatModel.java:97) at svm.SvmTrain.train(SvmTrain.java:60) at svm.SvmTrain.main(SvmTrain.java:34)
my test image 134x36 ,30~40kb. I fixed the code CV_32FC1 ->CV_32S . what is mean "while the traindata must be of float type(correct here, wrong in your issue) "
@berak ....I seem to be successful .but I do not know why . correct code : svm.train(trainData.getSamples(),Ml.ROW_SAMPLE,trainData.getResponses()); wrong code : svm.train(trainData);