!752 static S imageID = "#1004061"; !include #1004250 // Eye !include #1004067 // XRecognizableImage static File infoFile; static InputImage inputImage; static ImageInfo ii; static XRecognizableImage ri; static ImageReader recognizer; static volatile L debugItems; static JRecognizedText textArea; sbool triggerRecog; volatile sbool recognizing; p { RGBImage img = new RGBImage(loadImg(imageID)); // load imageInfo ii = new ImageInfo; infoFile = getProgramFile("imageInfo.tree"); S iitext = loadTextFile(infoFile); if (nempty(iitext)) ii.getTree().set(Tree.parse(iitext)); ri = new XRecognizableImage; ri.imageInfo = ii; ri.setImage(img); ri.setDrawMarkLines(true); ri.setCorrections(ii.getCorrections()); inputImage = new InputImage(img.toBW()); textArea = new JRecognizedText; loadRecognizer(); if (recognizer == null) recognizer = new SaR(new LineFinder, new FlexibleSegmenter, new CompareImages); recog(recognizer); learnCorrections(); recog(recognizer); JFrame frame = showFrame(centerAndSouth(vgrid(ri, textArea), null /*jbutton("Recognize again", r { recog(); })*/)); swingTimer(frame, 100, r{ if (triggerRecog && !recognizing) { triggerRecog = false; recogInBackground(); } }); } svoid saveImageInfo() { saveTextFile(infoFile, ii.getTree().toString()); ri.setCorrections(ii.getCorrections()); ri.repaintImageSurface(); } svoid recognizerModified() { S s = recognizer.getDescription(); saveTextFile(getProgramFile("recognizer.tree"), s); print("Saved recognizer (" + l(s) + " chars)"); triggerRecog = true; } svoid loadRecognizer() { S s = loadTextFile(getProgramFile("recognizer.tree")); if (nempty(s)) recognizer = OCRUtil.makeImageReader(s); } svoid learnCorrections() { S desc = recognizer.getDescription(); CharacterLearner characterLearner = recognizer.getCharacterLearner(); if (characterLearner != null) for (Correction c : ii.getCorrections()) { Rectangle r = c.getRectangle(); Point p = new Point(r.x+r.width/2, r.y+r.height/2); Subrecognition subrecognition = findSubrecognition(p); continue if subrecognition == null; ImageWithMarkLines imageWithMarkLines = new ImageWithMarkLines(subrecognition.image, subrecognition.topLine, subrecognition.baseLine); characterLearner.learnCharacter(imageWithMarkLines, c.getText()); } if (neq(recognizer.getDescription(), desc)) recognizerModified(); } static Subrecognition findSubrecognition(Point p) { for (DebugItem item : debugItems) if (item.data instanceof Subrecognition) { Subrecognition s = (Subrecognition) item.data; Rectangle r = new Rectangle(s.clip); r.grow(1, 1); if (r.contains(p)) return s; } null; } svoid recog(ImageReader rec) { long t = now(); // do it! rec.setCollectDebugInfo(true); RecognizedText rt; time { rt = rec.extendedReadImage(inputImage); } debugItems = rec.getDebugInfo(); done(t, "recog"); recogDone(rt); } static ImageReader cloneRecognizer(ImageReader recognizer) { ret OCRUtil.makeImageReader(recognizer.getDescription()); } svoid recogDone(final RecognizedText rt) { awtIfNecessary { print("Debug items: " + l(debugItems)); ri.setDebugInfo(debugItems); S text = rt != null ? rt.text : ""; textArea.setText(text, debugItems); ri.repaintImageSurface(); } } svoid recogInBackground() { recognizing = true; final ImageReader rec = cloneRecognizer(recognizer); thread "Recognizing" { try { recog(rec); } finally { recognizing = false; } } }