Android SVM.predict not work properly

asked 2018-03-15 05:23:04 -0600

jikolp95 gravatar image

updated 2018-03-15 08:18:11 -0600

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);
                        }
edit retag flag offensive close merge delete

Comments

@berak, help me!

jikolp95 gravatar imagejikolp95 ( 2018-03-15 05:23:50 -0600 )edit

"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 gravatar imageberak ( 2018-03-15 05:48:18 -0600 )edit
1

@berak i changed my question to "correct" :))

jikolp95 gravatar imagejikolp95 ( 2018-03-15 08:14:54 -0600 )edit

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 gravatar imageberak ( 2018-03-15 08:16:42 -0600 )edit
1

@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.

jikolp95 gravatar imagejikolp95 ( 2018-03-15 08:28:29 -0600 )edit

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 gravatar imageberak ( 2018-03-15 08:34:00 -0600 )edit
1

@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

jikolp95 gravatar imagejikolp95 ( 2018-03-15 09:20:02 -0600 )edit

@berak are you here?

jikolp95 gravatar imagejikolp95 ( 2018-03-15 23:20:42 -0600 )edit

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 gravatar imageberak ( 2018-03-16 01:46:42 -0600 )edit

@berak, i have no idea too. On pc it is work properly, i tried on 1000 pictures. But in android ...( help me please!

jikolp95 gravatar imagejikolp95 ( 2018-03-16 02:44:03 -0600 )edit