Digit recognition : training responses

asked 2015-02-05 03:53:28 -0500

Alexandre G. gravatar image

updated 2015-02-05 12:11:13 -0500

berak gravatar image

I have the following code I'm using for digit recognition. Unfortunately the results are quite disappointing. I'm not sure but I feel like I'm doing something wrong with the training responses.

private static final int classes = 10;
private Mat train_responses = new Mat(1, 10, CvType.CV_32SC1);
private double myint[] = new double[10];
private Mat train_samples = new Mat();
private CvKNearest knn = new CvKNearest();

public OCRManager() {

}

public void mainOCR() {

    learnFromImages();

    for (int i = 0 ; i < 10 ; i++) {
        String path = Environment.getExternalStorageDirectory().toString() + "/Pictures/ocr/" + i + ".png";
        Mat img = Highgui.imread(path);
        img.convertTo(img, CvType.CV_32FC1);            
        Mat imgResized = preProcessImage(img);
        Size dsize = new Size(20,30);
        Imgproc.resize(imgResized, imgResized, dsize);

        Mat results = new Mat();
        Mat responses = new Mat();
        Mat dists = new Mat();
        Mat sample = new Mat();
        sample.push_back(imgResized);

        imgResized.convertTo(imgResized, CvType.CV_32FC1);
        sample.convertTo(sample, CvType.CV_32FC1);
        results.convertTo(results, CvType.CV_32FC1);
        dists.convertTo(dists, CvType.CV_32FC1);
        responses.convertTo(responses, CvType.CV_32FC1);

        imgResized = imgResized.reshape(1,1);

        float numberDetected = knn.find_nearest(imgResized, 1, results, responses, dists);
        Log.e("find nearest", "nearest found for " + i + " = " + numberDetected);
    }
}

private void learnFromImages() {
    for (int i = 0; i < classes ; i++) {
        String path = Environment.getExternalStorageDirectory().toString() + "/Pictures/ocr/" + i + ".png";
        Mat img = Highgui.imread(path);
        img.convertTo(img, CvType.CV_32FC1);            
        Mat imgResized = preProcessImage(img);
        Size dsize = new Size(20,30);
        Imgproc.resize(imgResized, imgResized, dsize);
        imgResized.convertTo(imgResized, CvType.CV_32FC1);
        imgResized = imgResized.reshape(1, 1);
        train_samples.push_back(imgResized);
        myint[i] = i;
    }

    train_responses.put(0,0,myint);
    knn.train(train_samples, train_responses);
}

For testing purposes, I'm trying to recognize the very same image samples I used for training. As a result, I have this kind of responses

E/find nearest﹕ nearest found for 0 = 0.0
E/find nearest﹕ nearest found for 1 = 1.0
E/find nearest﹕ nearest found for 2 = 1.5523267E9
E/find nearest﹕ nearest found for 3 = 1.1240243E9
E/find nearest﹕ nearest found for 4 = 1.5930442E9
E/find nearest﹕ nearest found for 5 = 1.5930445E9
E/find nearest﹕ nearest found for 6 = 64.0
E/find nearest﹕ nearest found for 7 = 29.0
E/find nearest﹕ nearest found for 8 = 4.0
E/find nearest﹕ nearest found for 9 = 8.0

This if for k = 1 (2nd argument of find_nearest method). With k=32, I have 0.0 all around. What am I doing wrong ? This is a bit overwhelming.

edit retag flag offensive close merge delete

Comments

I think, k value should be lower than number of classes. So when you put k=32 you have result 0.0

DanielQ gravatar imageDanielQ ( 2015-08-06 15:36:47 -0500 )edit