!7 sbool real = false; sS data = [[ RecognizedText(r=Rect(h=12, w=54, x=627, y=309), text=Scored(score=fl "1.0", v="Confirm")) RecognizedText(r=Rect(h=12, w=36, x=684, y=309), text=Scored(score=fl "1.0", v="close")) RecognizedText(r=Rect(h=10, w=23, x=494, y=359), text=Scored(score=fl "0.9542266", v="you")) RecognizedText(r=Rect(h=11, w=39, x=548, y=358), text=Scored(score=fl "1.0", v="about")) RecognizedText(r=Rect(h=10, w=13, x=592, y=359), text=Scored(score=fl "0.9918628", v="to")) RecognizedText(r=Rect(h=11, w=33, x=610, y=358), text=Scored(score=fl "0.998467", v="close")) RecognizedText(r=Rect(h=10, w=6, x=648, y=359), text=Scored(score=fl "0.8560784", v="3")) RecognizedText(r=Rect(h=11, w=31, x=659, y=358), text=Scored(score=fl "1.0", v="tabs.")) RecognizedText(r=Rect(h=13, w=50, x=695, y=359), text=Scored(score=fl "0.9463429", v="Areyou")) RecognizedText(r=Rect(h=10, w=33, x=812, y=359), text=Scored(score=fl "0.9773897", v="want")) RecognizedText(r=Rect(h=10, w=13, x=850, y=359), text=Scored(score=fl "0.9918628", v="to")) RecognizedText(r=Rect(h=11, w=65, x=868, y=358), text=Scored(score=fl "1.0", v="continue?")) RecognizedText(r=Rect(h=8, w=20, x=523, y=361), text=Scored(score=fl "0.97618467", v="are")) RecognizedText(r=Rect(h=8, w=28, x=751, y=361), text=Scored(score=fl "0.9821385", v="sure")) RecognizedText(r=Rect(h=11, w=23, x=783, y=361), text=Scored(score=fl "0.9744504", v="you")) RecognizedText(r=Rect(h=11, w=43, x=765, y=406), text=Scored(score=fl "0.99504626", v="Cancel")) RecognizedText(r=Rect(h=11, w=35, x=855, y=406), text=Scored(score=fl "1.0", v="Close")) RecognizedText(r=Rect(h=11, w=28, x=895, y=406), text=Scored(score=fl "0.9762714", v="tabs")) ]]; p { if (real) recognize(shootScreenHidingConsole()); else { recognize(loadImage2(#1101350)); recognize(loadImage2(#1101351)); } } svoid recognize(BufferedImage img) { L expected = map unstruct(tlft(data)); L actual = ocr_recognizeMultiLine_scored(img); MultiMap byWord = multiMapIndexOverMethod(actual, 'text); tryShift(expected, byWord, pt(0, 0)); pnlStruct(multiSetAsMap_popularFirst(possibleShifts(expected, byWord))); //tryShift(expected, byWord, averagePt(map centerOfRect(collect('r, actual)))); } static MultiSet possibleShifts(L expected, MultiMap byWord) { new MultiSet ms; for (RecognizedText t : expected) { L list = byWord.get(t.text()); print(t.text() + " " + t.r + " => " + struct(collect('r, list))); if (empty(list)) continue; final Pt p = rectCenter(t.r); for (RecognizedText r : list) ms.add(ptDiff(rectCenter(r.r), p)); } ret ms; } static double tryShift(L expected, MultiMap byWord, Pt shift) { double closeness = 0; for (RecognizedText t : expected) { L list = byWord.get(t.text()); print(t.text() + " " + t.r + " => " + struct(collect('r, list))); if (empty(list)) continue; final Pt p = ptAdd(rectCenter(t.r), shift); double dist = sqrt(minOfDoubles(map(list, func(RecognizedText r) { ptDistanceSquared(p, rectCenter(r.r)) }))); print("dist=" + dist); closeness += 1/(dist+1); } closeness /= l(expected); print("Closeness: " + closeness); ret closeness; }