Ask Your Question
0

How to use KNearest in java?

asked 2016-03-11 05:34:47 -0500

Max3 gravatar image

Hi! I don't know how to use KNearest in OpenCV 3.0 in java. I really can't find any documentation in java. Can someone help me? Thanks in advance!

edit retag flag offensive close merge delete

Comments

have a look at the docs , try a bit, and come back with more specific problems ?

berak gravatar imageberak ( 2016-03-12 01:05:00 -0500 )edit
1

As you can see java documentation doesn't say much. However I have to detect digits, I can't use third part libraries so I can't use OCR like tesseract or similar. I have 500 image samples for each digit (size 20x20) and I should want to use them to train my KNearest object. I have to use the method:

KNearest.train(Mat samples, int layout, Mat responses);

1) But in which format should I put my samples Mat? And what int layout stay for? Then if I understand I have to use the method:

KNearest.findNearest(Mat samples, int k, Mat results);

2) In this function my Mat samples is the Mat responses of train function, right? But in which format will be my Mat results? Thanks in advance for your answers and sorry for my English^^

Max3 gravatar imageMax3 ( 2016-03-12 08:02:55 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2016-03-13 04:17:08 -0500

berak gravatar image

for opencv machinelearning you will have to convert your features to float, and flatten them int o a single row per feature. then you stack your features into a single huge Mat, and build a response/labels Mat with one number (the label/id) per feature row:

      [data]         [labels]
      feature1        1
      feature2        1
      feature3        2
      feature4        2
      feature5        1
      ...

the layout will be either ROW_SAMPLE (most commonly used) or COL_SAMPLE

here's some code to try:

import org.opencv.core.*;
import org.opencv.imgproc.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.ml.*;
import org.opencv.utils.*;
import java.util.*;


class SimpleSample {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

    public static void main(String[] args) {
        // samples/data/digits.png, have a look at it.
        Mat digits = Imgcodecs.imread("digits.png", 0);
        // setup train/test data:
        Mat trainData = new Mat(),
            testData = new Mat();
        List<Integer> trainLabs = new ArrayList<Integer>(),
            testLabs = new ArrayList<Integer>();
        // 10 digits a 5 rows:
        for (int r=0; r<50; r++) { 
            // 100 digits per row:
            for (int c=0; c<100; c++) {
                // crop out 1 digit:
                Mat num = digits.submat(new Rect(c*20,r*20,20,20));
                // we need float data for knn:
                num.convertTo(num, CvType.CV_32F);
                // 50/50 train/test split:
                if (c % 2 == 0) {
                    // for opencv ml, each feature has to be a single row:
                    trainData.push_back(num.reshape(1,1));
                    // add a label for that feature (the digit number):
                    trainLabs.add(r/5);
                } else {
                    testData.push_back(num.reshape(1,1));
                    testLabs.add(r/5);
                }
            }                
        }

        // make a Mat of the train labels, and train knn:
        KNearest knn = KNearest.create();
        knn.train(trainData, Ml.ROW_SAMPLE, Converters.vector_int_to_Mat(trainLabs));
        // now test predictions:
        for (int i=0; i<testData.rows(); i++)
        {
            Mat one_feature = testData.row(i);
            int testLabel = testLabs.get(i);

            Mat res = new Mat();
            float p = knn.findNearest(one_feature, 1, res);
            System.out.println(testLabel + " " + p + " " + res.dump());
        }

        //// hmm, the 'real world' test case probably looks more like this:
        //// make sure, you follow the very same preprocessing steps used in the train phase:
        //  Mat one_feature = Imgcodecs.imread("one_digit.png", 0);
        //  Mat feature; one_feature.convertTo(feature, CvTypes.CV_32F);
        //  Imgproc.resize(feature, feature, Size(20,20));
        //  int predicted = knn.findNearest(feature.reshape(1,1), 1);
    }
}
edit flag offensive delete link more

Comments

1

Perfect explanation! I really thank you! That's what i was looking for!

Max3 gravatar imageMax3 ( 2016-03-15 12:28:29 -0500 )edit

Could you please include the link for the used picture ?

NejiSoltani gravatar imageNejiSoltani ( 2018-01-30 09:51:16 -0500 )edit
berak gravatar imageberak ( 2018-01-30 10:01:32 -0500 )edit
1

Thanks ! you just saved me

NejiSoltani gravatar imageNejiSoltani ( 2018-01-30 10:49:46 -0500 )edit

Hi. Can i train data using arraylist?

j0hnd3v gravatar imagej0hnd3v ( 2018-02-01 06:49:35 -0500 )edit

@j0hnd3v -- no. it needs a single Mat with consecutive data.

(but ofc. you can collect your data into a list, and convert to Mat for training, if that's easier for you)

berak gravatar imageberak ( 2018-02-01 07:27:25 -0500 )edit

because im planning to train rgb values and compare it with the capture image rgb values. is it possible ?

j0hnd3v gravatar imagej0hnd3v ( 2018-02-01 07:33:07 -0500 )edit

maybe you want to ask a new question about it ?

berak gravatar imageberak ( 2018-02-01 07:40:02 -0500 )edit
1

Sorry for asking it here. I already asked a question

j0hnd3v gravatar imagej0hnd3v ( 2018-02-01 07:50:02 -0500 )edit

no worries, let's just not clutter this one too much !

berak gravatar imageberak ( 2018-02-01 08:00:02 -0500 )edit
Login/Signup to Answer

Question Tools

2 followers

Stats

Asked: 2016-03-11 05:34:47 -0500

Seen: 2,656 times

Last updated: Mar 13 '16