Android SVM.predict not work properly
I trained svm for detect painted and unpainted bubbles in picture. Opencv version is 3.4.1. It is work like a charm. Prediction (svm.predict()) work correct, like a charm too. Here is my code below.
private static String pathNeg = "E:\\Android\\data\\negativo";
private static String pathPos = "E:\\Android\\data\\positivo";
private static String XML = "E:\\Android\\data\\model.xml";
static {
System.load("E:/Android/opencv/build/java/x64/opencv_java340.dll");
}
public static void main(String[] args) {
final HOGDescriptor hog = new HOGDescriptor(new Size(16, 16), new Size(8, 8), new Size(4, 4), new Size(4, 4), 9);
Mat trainLabel = new Mat();
Mat trainData = new Mat();
for (File file : new File(pathPos).listFiles()) {
if (file.getAbsolutePath().endsWith("jpg")) {
final Mat img = Imgcodecs.imread(file.getAbsolutePath());
MatOfFloat descriptors = new MatOfFloat();
Imgproc.resize(img, img, new Size(16, 16));
hog.compute(img, descriptors);
Mat mat = descriptors.reshape(1, 1);
trainData.push_back(mat);
trainLabel.push_back(Mat.ones(new Size(1, 1), CvType.CV_32S));
}
}
for (File file : new File(pathNeg).listFiles()) {
if (file.getAbsolutePath().endsWith("jpg")) {
Mat img = Imgcodecs.imread(file.getAbsolutePath());
MatOfFloat descriptors = new MatOfFloat();
Imgproc.resize(img, img, new Size(16, 16));
hog.compute(img, descriptors);
Mat mat = descriptors.reshape(1, 1);
trainData.push_back(mat);
trainLabel.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32S));
}
}
System.out.println("trainData rows:" + trainData.rows());
System.out.println("trainLabel rows:" + trainLabel.rows());
final SVM svm = SVM.create();
svm.setKernel(SVM.RBF);
trainData.convertTo(trainData, CvType.CV_32FC1);
svm.trainAuto(trainData, Ml.ROW_SAMPLE, trainLabel);
svm.save(XML);
}
Now i am using trained xml model in android app, but prediction svm.predict() not work properly. Not give right prediction. I am using Opencv Android sdk 3.4.0. And here is my code below
Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "model.xml"));
final SVM svm = SVM.load(uri.getPath());
final HOGDescriptor hog = new HOGDescriptor(new Size(16, 16), new Size(8, 8), new Size(4, 4), new Size(4, 4), 9);
Mat answerROI = src.submat(rects.get(passedQuestionsCount));
MatOfFloat descriptors = new MatOfFloat();
Imgproc.resize(answerROI, answerROI, new Size(16, 16));
hog.compute(answerROI, descriptors);
Mat mat = descriptors.reshape(1, 1);
if (svm.predict(mat) > 0.0) {
bubbledRect = rects.get(passedQuestionsCount);
}
@berak, help me!
"it is not work properly" -- it is not question properly ;)
you'll have to explain, what you expect, what you get, and where the problem is, else we cannot help you !
also, does the opencv version on pc/android differ ?
@berak i changed my question to "correct" :))
just a suspicion (since you train it on color images):
how do you get the images, on android ? any chance it's a bgr/rgb problem ?
(also, it's probably a good idea, to do all of it in grayscale)
@berak I originally did this like this
Mat gray = new Mat(); Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
It didn't work (
I get image in android from camera.
again, can we rule out bgr/rgb issues ? (opencv is BGR, while android usually has it RGBA) check, if your conversions are correct.
are the hog features on both machines the same ? (try with one image on both machines & compare)
@berak hog features on both machines have small difference in value! Like 0.01015077531337738 and 0.01506397407501936, 0.03719655051827431 and 0.033248357474803925, 0.35999664664268494 and 0.36015719175338745,
and so on, but approximately equal
@berak are you here?
i'm a bit out of ideas ;(
if it's not the image, and not the hog feature, what then ?
you could try to e.g. check svm.getKernelType(), etc, and see, if it read the model correctly, but hmm
@berak, i have no idea too. On pc it is work properly, i tried on 1000 pictures. But in android ...( help me please!