Hi everyone,
I am trying to train a SVM and use it to classify faces. I am trying to translate some recent OpenCV C++ SVM examples to Java as I cannot find a recent Java one. I am running into some errors and was wondering if someone could point me to a Java tutorial or help me resolve my errors. I am using Java OpenCV 3.4.0.
I am unable to successfully train the SVM and, once I am able to, I am not sure how to use it for classification. What am I doing wrong when trying to train? Once training is fixed, can I test all the testing images at once or do I need to test them one-by-one? How will the classification results be returned? Thank you for your help!
Here is my code:
TRAINING_DATA - Rows:75 Cols:128 (CV_FC1) TRAINING_LABELS - Rows:75 Cols:1 (CV_8UC1) TESTING_DATA - Rows:75 Cols:128 (CV_FC1) TESTING_LABELS - Rows:75 Cols:1 (CV_8UC1)
public static void main(String[] args){
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
String DATABASE = "yalefaces_aligned";
Net NET = Dnn.readNetFromTorch("openface.nn4.small2.v1.t7");
boolean CLAHE_ON = false;
boolean FACENET_ON = true;
boolean BIF_ON = false;
int BIF_bands = 8;
int BIF_rots = 8;
ArrayList<Integer> training_labels_array = new ArrayList<Integer>();
ArrayList<Integer> testing_labels_array = new ArrayList<Integer>();
Mat TRAINING_DATA = new Mat();
Mat TESTING_DATA = new Mat();
// Load training and testing data
File[] directories = new File(DATABASE).listFiles();
for(int i = 0; i < directories.length; i++){
File[] files = directories[i].listFiles();
for(int j = 0; j < 5; j++){
Mat image = Imgcodecs.imread(files[j].getAbsolutePath());
Mat training_feature = Feature_Extractor.extract_feature(image, CLAHE_ON, FACENET_ON, NET, BIF_ON, BIF_bands, BIF_rots);
TRAINING_DATA.push_back(training_feature);
training_labels_array.add((i+1));
}
for(int j = 5; j < files.length; j++){
Mat image = Imgcodecs.imread(files[j].getAbsolutePath());
Mat testing_feature = Feature_Extractor.extract_feature(image, CLAHE_ON, FACENET_ON, NET, BIF_ON, BIF_bands, BIF_rots);
TESTING_DATA.push_back(testing_feature);
testing_labels_array.add((i+1));
}
}
// Put training and testing labels into Mats
Mat TRAINING_LABELS = Mat.zeros(TRAINING_DATA.rows(), 1, CvType.CV_8UC1);
for(int i = 0; i < training_labels_array.size(); i++){
TRAINING_LABELS.put(i, 0, training_labels_array.get(i));
}
Mat TESTING_LABELS = Mat.zeros(TESTING_DATA.rows(), 1, CvType.CV_8UC1);
for(int i = 0; i < testing_labels_array.size(); i++){
TESTING_LABELS.put(i, 0, testing_labels_array.get(i));
}
System.out.println("TRAINING_DATA - Rows:" + TRAINING_DATA.rows() + " Cols:" + TRAINING_DATA.cols());
System.out.println("TRAINING_LABELS - Rows:" + TRAINING_LABELS.rows() + " Cols:" + TRAINING_LABELS.cols());
//System.out.println(TRAINING_LABELS.dump());
System.out.println("TESTING_DATA - Rows:" + TESTING_DATA.rows() + " Cols:" + TESTING_DATA.cols());
System.out.println("TESTING_LABELS - Rows:" + TESTING_LABELS.rows() + " Cols:" + TESTING_LABELS.cols());
//System.out.println(TRAINING_LABELS.dump());
// Train SVM
SVM svm = SVM.create();
svm.setKernel(SVM.LINEAR);
svm.setType(SVM.C_SVC);
// errors here
svm.train(TRAINING_DATA, Ml.ROW_SAMPLE, TRAINING_LABELS);
Mat RESULTS = new Mat();
// do i need to predict test features one-by-one?
// what is flags?
svm.predict(TESTING_DATA, RESULTS, flags);
}