How to recognize all the letters in a picture with opencv , KNN and java

asked 2016-04-19 08:46:23 -0600

jack1 gravatar image

i have to write a java program that recognizes all the letters in a picture taken with android camera .I tried KNN method but i could only recognize a single letter in the picture and i want to recognize all the letters .Can someonr help me. This is my code

public void train (){


    //Creating Training Data
     Mat trainData = new Mat(); 
     Mat train_labels = new Mat();

    for (int i =1; i <15; i++) {
        String path = Environment.getExternalStorageDirectory().toString() + "/Pictures/New Folder/" + i + ".png";

    Mat img =Imgcodecs.imread(path);
    Log.i(TAG,"error debug: "+i+img.empty());

    img.convertTo(img, CvType.CV_32FC1); // Convert  to float
    Size dsize = new Size(25,25); 
     Imgproc.resize(img, img, dsize); 

     img.convertTo(img, CvType.CV_32FC1);
     Mat imgResized = img.reshape(1, 1); //make continuous

     trainData.push_back(imgResized);

    train_labels.push_back(new Mat (1,1,CvType.CV_32FC1,new Scalar(i)));// add 1 item

    }

        Mat response=new Mat();
        Mat tmp;
        tmp= train_labels.reshape(1,1); //make continuous
        tmp.convertTo(response,CvType.CV_32FC1); // Convert  to float*/


     KNearest knn = KNearest.create();
     knn.train(trainData,Ml.ROW_SAMPLE, train_labels);




     //For Storing training data

 String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() ;


Bitmap bmpOut1 = Bitmap.createBitmap(trainData.cols(), trainData.rows(), Bitmap.Config.ARGB_8888);
Bitmap bmpOut2 = Bitmap.createBitmap(response.cols(), response.rows(), Bitmap.Config.ARGB_8888);

response.convertTo(response,CvType.CV_8UC1);
trainData.convertTo(trainData,CvType.CV_8UC1);

Utils.matToBitmap(trainData, bmpOut1);
Utils.matToBitmap(response, bmpOut2);
//File file = new File(path);
// file.mkdirs();
File file = new File(path, "train.png");
File file2 = new File(path, "response.png");

OutputStream fout = null;
OutputStream fout2 = null;

try {
    fout = new FileOutputStream(file);
    fout2 = new FileOutputStream(file2);

    BufferedOutputStream bos = new BufferedOutputStream(fout);
    BufferedOutputStream bos2 = new BufferedOutputStream(fout2);

    bmpOut1.compress(Bitmap.CompressFormat.PNG, 100, bos);
    bos.flush();
    bos.close();
    bmpOut1.recycle();

    bmpOut2.compress(Bitmap.CompressFormat.PNG, 100, bos2);
    bos2.flush();
    bos2.close();
    bmpOut2.recycle();

} catch (FileNotFoundException e) {
    e.printStackTrace();
}

catch (IOException e) {
    e.printStackTrace();
}


 //For Accessing training data in BMP file  


    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inScaled = false;
    Bitmap blankBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.train,o);
    int trainWidth = blankBitmap.getWidth();
    int trainHeight = blankBitmap.getHeight();



    Mat trainData2 = new Mat();
    Utils.bitmapToMat(blankBitmap,trainData2);

    Bitmap blankBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.response,o);
    int resWidth = blankBitmap2.getWidth();
    int resHeight = blankBitmap2.getHeight();

    Log.i(TAG,"res width "+ resWidth +" res Height"+ resHeight);
    Mat response2 = new Mat();
    Utils.bitmapToMat(blankBitmap2,response2);

    Log.i(TAG,"response2 width "+ response2.cols() +" res Height"+ response2.rows());

    Mat response3 = new Mat();
    Mat trainData3 = new Mat();

    Imgproc.cvtColor(response2,response2,Imgproc.COLOR_BGRA2GRAY);       // 1. change the number of channels
    Imgproc.cvtColor(trainData2,trainData2,Imgproc.COLOR_BGRA2GRAY);
    response2.convertTo(response3,CvType.CV_32FC1);
    trainData2.convertTo(trainData3,CvType.CV_32FC1);



    KNearest knn2 = KNearest.create();
    knn2.train(trainData3,Ml.ROW_SAMPLE, response3);


   Mat img = Imgcodecs.imread("/storage/emulated/0/DCIM/Camera/IMG.png");
   Log.i(TAG,"error1 img: "+img.empty());          
    Mat test = new Mat();
    Imgproc.resize(img,test, new Size(25,25) );
    test.convertTo(test, CvType.CV_32FC1);

    Mat results = new Mat();
    Mat responses = new Mat();
    Mat dists = new Mat();

    float label = knn.findNearest(test.reshape(1,1), 1,results,responses,dists);
    Log.i ...
(more)
edit retag flag offensive close merge delete

Comments

  • how many different labels are there ? (you give every image its own label, while there seem to be only "N" and "E", this is all a bit murky.)
  • 15 train images will never be enough.
  • try to increase K in findNearest, e.g. to 3
berak gravatar imageberak ( 2016-04-20 04:56:35 -0600 )edit

Yes i know that i should complete all train images but my problem was that i can't read all letters in the image given by( Mat img = Imgcodecs.imread("/storage/emulated/0/DCIM/Camera/IMG.png");) this code allows me to just read 1 letter not all the letters in the image .I tried to use bounding boxes ,then extract each letters from each box and finally apply KNN algorithm for each one .Is it a good idea ?

jack1 gravatar imagejack1 ( 2016-04-20 07:00:55 -0600 )edit
sturkmen gravatar imagesturkmen ( 2016-04-24 19:01:29 -0600 )edit