!7 concept GrabbedImage { long lastScreenshotTime; Rect lastRect; BWImage image; S md5; int count; BWImage visualizedSplit; new L rects; new L characters; new L characterMD5s; L groupedRecognition; S recognition; } concept RecogInfo { new L lines; } concept SeedLoaded { S snippetID; } static SimpleRecognizer sr; sbool fullSearch, closeAfterTeach; p { prepare(); new ShowAndRecognize(new Concepts("#1005951").load()); } svoid prepare() { setDBProgramID("#1006104"); // use DB of v1 conceptsAndBot(); //deleteConcepts(GrabbedImage); // legacy? loadSeed(#3000425); sr = new SimpleRecognizer; sr.load(joinLines(uniq(RecogInfo).lines)); if (fullSearch) { print("Enabling full search..."); sr.fullSearchMap = reverseMap(getLearnedCharacters2()); print("...done."); } } svoid loadSeed(S snippetID) { snippetID = fsI(snippetID); if (!hasConcept(SeedLoaded, snippetID)) { print("Seeding with " + snippetID + "..."); RecogInfo ri = uniq(RecogInfo); int l = l(ri.lines); setAddAllFirstQuick(ri.lines, toLinesFullTrim(loadSnippet(snippetID))); l = l(ri.lines)-l; print("Got " + n(l, "new lines")); if (l != 0) ri.change(); uniq(SeedLoaded, snippetID); } } sclass ShowAndRecognize { Concepts in; // contains GrabbedImage's JTable table; *(Concepts *in) { update(); } void update { try { if (table != null) { frameIcon(table, "#1005541"); setFrameTitle(table, "Calculating - Recognitions"); } new L data; for (GrabbedImage gi : sortByFieldDesc(in.list(GrabbedImage), "lastScreenshotTime")) { if (gi.visualizedSplit == null) { L rects = horizontalAutoSplit2ThenAutoCrop(gi.image); cset(gi, visualizedSplit := new BWImage(mergeImagePartsHorizontally(gi.image.toRGB(), rects))); for (Rect r : rects) { BWImage cImg = gi.image.clip(r); gi.rects.add(r); gi.characters.add(cImg); gi.characterMD5s.add(md5OfBWImage(cImg)); } } /*S rec = sr.recognizeCheat(gi.image); if (rec != null) gi.recognition = "! " + rec; else*/ gi.groupedRecognition = sr.recognizeGrouped(gi.image); gi.recognition = ocr_unescape(ocr_joinGroups(gi.groupedRecognition)); data.add(ll(gi.md5, gi.image.getBufferedImage(), gi.recognition, gi.visualizedSplit.getBufferedImage())); } // sort by length of recognized text (longest first) data = sortedDescAccordingTo(data, func(L l) { l(_get(l, 2)) }); bool first = table == null; sexyTable_drag = false; table = showTableWithImages("Recognitions", splitAtSlash("MD5/Image/Recognition/Split"), data, table); if (!first) ret; awt { maximizeFrame(table); table.setRowHeight(40); tablePopupMenuFirst(table, voidfunc(JPopupMenu menu, final int row) { addMenuItem(menu, "Teach...", r { teachRow(row) }); addMenuItem(menu, "Mark on screen", r-thread { Rect r; pointArrowsToArea(r = parseRect(getTableLine(table, row).get(3))); print("Marking: " + r); }); }); onEnterAndDoubleClick(table, voidfunc(int row) { teachRow(row); }); gcAndPrintMemoryInfo(); awtCalcOnConceptChanges(table, 1000, 1000, r { update() }, false); } } finally { frameIcon(table, null); setFrameTitle(table, "Recognitions"); } } void teachRow(int row) { S md5 = cast getTableCell(table, row, 0); final GrabbedImage gi = findConcept(in, GrabbedImage, +md5); print("characterMD5s: " + joinWithSpace(gi.characterMD5s)); final JTextField tf = jTypeWriterTextField(ocr_joinAsGrouped(gi.groupedRecognition)); final JCheckBox grouped = jCheckBox("grouped (" + ocrCharGroupingHelpText() + ")", true); final JButton btnSubmit = jbutton("Submit", r { S s = trim(tf.getText()); bool group = isChecked(grouped); L rects = gi.rects; if (group) { rects = ocr_groupRects(rects, s); s = ocr_unmerge(s); } saveScreenClip(gi.image); L characterMD5s = md5OfBWImageParts(gi.image, rects); if (sr.fullSearchMap != null) for i over rects: sr.fullSearchMap.put(gi.image.clip(rects.get(i)), characterMD5s.get(i)); S line = "The images " + quote(join(" ", characterMD5s)) + " are the " + (group ? "grouped " : "") + "characters " + quote(s) + "."; print(">> " + line); logQuoted(glyphTeachLog(), "[" + localDateWithSeconds() + "] Image " + ocrMD5OfBWImage(gi.image) + ": " + line); RecogInfo ri = uniq(RecogInfo); if (setAddOrMoveToEnd(ri.lines, line)) { print("Feeding to recognizer."); sr.load(line); ri.change(); } disposeFrame(tf); if (closeAfterTeach) disposeFrame(table); }); onUpdateAndNow(ll(tf, grouped), r { S s = trim(tf.getText()); btnSubmit.setEnabled((isChecked(grouped) ? ocr_glyphCount(s) : l(dropSpaces(s))) == l(gi.characters)); }); growFrameSouth(50, showFormTitled("Teach", "Image:" , jscroll(zoomedImageSurface(2, gi.image.getBufferedImage())), "Split:" , jscroll(zoomedImageSurface(2, gi.visualizedSplit.getBufferedImage())), "Meaning:", tf, "", grouped, "", btnSubmit)); awtLater(tf, 100, r { print("select all"); tf.selectAll() }); } }