how to Use KNN for OCR [closed]
so iv had this question every where and no answers are provided i am trying to recognize a digit (image)
and the training data set is
the result is 35 from the KNN.findNearest so my question is what does this number mean or how could i use it to say that the input data is equal to ٢
here is my code
void run() throws IOException {
String PATH_numbers = "/home/tomna/NetBeansProjects/Parking-tracking-system/src/mainclass/chdataset/Numb";
Mat img = Imgcodecs.imread("/home/tomna/NetBeansProjects/Parking-tracking-system/src/mainclass/characters/6.jpg");
Mat trainingData = new Mat();
Mat trainingLabels = new Mat();
int i=1;
int j=1;
for (File file : new File(PATH_numbers).listFiles()) {
Mat image = getMat(file.getAbsolutePath());
image.convertTo(image, CvType.CV_32F); // Convert to float
Imgproc.resize(image, image, new Size(74, 60));
Mat imgresized = image.reshape(1, 1); // make continous
trainingData.push_back(imgresized);
trainingLabels.push_back(new Mat(1, 1, CvType.CV_32SC1, new Scalar(i)));
if(j%5==0){
i++;
}
j++;
}
Mat response = new Mat();
Mat tmp;
tmp = trainingLabels.reshape(1, 1); // make continuous
tmp.convertTo(response, CvType.CV_32F); // Convert to float
KNearest knn = KNearest.create();
knn.train(trainingData, Ml.ROW_SAMPLE, tmp);
System.out.println(tmp.dump());
Mat test = new Mat();
Imgproc.cvtColor(img, test, Imgproc.COLOR_RGB2GRAY);
Imgproc.resize(test, test, new Size(74, 60));
test.convertTo(test, CvType.CV_32F);
Mat results = new Mat();
int label = (int) knn.findNearest(test.reshape(1, 1), 1, results);
System.out.println(label);
/// this part is an old part when i had only two images for each digit so i thought that the output correspond to number of images (trainingdata) ex if label if 1 means that the nearest neighbor is from image 1.. not sure
// if(label==1||label==2){
// System.out.println("٠");
// }else if(label==3||label==4){
// System.out.println("١");
// }else if(label==4||label==5){
// System.out.println("٢");
// }else if(label==6||label==7){
// System.out.println("٣");
// }else if(label==8||label==9){
// System.out.println("٤");
// }else if(label==10||label==11){
// System.out.println("٥");
// }else if(label==12||label==13){
// System.out.println("٦");
// }else if(label==14||label==15){
// System.out.println("٧");
// }else if(label==16||label==17){
// System.out.println("٨");
// }else if(label==18||label==19){
// System.out.println("٩");
// }else{
// System.out.println("Sorry");
// }
}
edit after using moment and hue moment with findcontours there will be sure some code wrong or logically wrong but i am new to this so bare with me and point it out. the output is always 1 no matter what the input user image is
here is the code
void run() throws IOException { String PATH_numbers = "/home/tomna/NetBeansProjects/Parking-tracking-system/src/mainclass/chdataset/Numb"; Mat img = Imgcodecs.imread("/home/tomna/NetBeansProjects/Parking-tracking-system/src/mainclass/characters/4.jpg"); Mat trainingData = new Mat(); Mat trainingLabels = new Mat();
for (File file : new File(PATH_numbers).listFiles()) {
Mat image = getMat(file.getAbsolutePath());
Imgproc.resize(image, image, new Size(74, 60));
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(image, contours ...
@berak is this question wrong or hard to answer ?
@LBerger i am new to all of this so if i did {new Scalar(1)" this will output only one label for all images so i guess putting every image in a label would fix this issue not sure. and yes all pixels in all the trainingdata is resized to 74*60 and the input image is also resized but not sure what do u mean by giving all pixel values as data
for the labels i think it should look like this but dont now how to implement 1,1,1,1,1,2,2,2,2,2,...9,9,9,9,9
@LBerger i made an edit now the output of the labels are as follow [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9] which means first 5 images have the same feature which means they will be assigned the same label
Hue moment is not good idea because letter 35 and 36 are equal. Try moment and hue moment. you must have contour letter
@LBerger i tried the hue moment and an error happened here is the code
@LBerger sorry man but the letter_recogn its hard to understand anything from it like 5 contributors its hard to trace anything soo i am gonna edit my question and hope you have an explanation to the error i am getting using moment and hue moment
@berak anything ?
i/5+1
would make nice labels (starting from 1)also, hu-moments are just 7 numbers, and don't make nice features for classification, usually.
oh, your resize() is the wrong way (you want vertical Rects, not hoizontal)
and yea, read grayscale images, the color is irrelevant here, no ?
also, do some processing, normalization, maybe deskew
@berak do you mean i use the code before the edit but the i/5+1 where will this be exactly
oh, sorry, :
@berak so the training label will be something like this [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9] and after changing this to this for both the training images and test image
now what processing could be done ?
Just in general, why would one still use KNN for OCR classification. Simple networks like LeNet are available in every deep learning package and perform WAY better. Take a look at those in my opinion.
A great example of the difference in performance: http://christopher5106.github.io/comp...
@StevenPuttemans do you have any links on how to implement it using java and opencv lib ?