How to recognize all the letters in a picture with opencv , KNN and java
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 ...
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 ?
take a look at http://stackoverflow.com/a/36412223/5...