Download Jar. Uses 408K of libraries. Click here for Pure Java version (9182L/63K).
1 | !7 |
2 | |
3 | sbool real = true, test = false; |
4 | static double threshold = 0.5; |
5 | |
6 | sS data = [[ |
7 | RecognizedText(r=Rect(h=12, w=54, x=627, y=309), text=Scored(score=fl "1.0", v="Confirm")) |
8 | RecognizedText(r=Rect(h=12, w=36, x=684, y=309), text=Scored(score=fl "1.0", v="close")) |
9 | RecognizedText(r=Rect(h=10, w=23, x=494, y=359), text=Scored(score=fl "0.9542266", v="you")) |
10 | RecognizedText(r=Rect(h=11, w=39, x=548, y=358), text=Scored(score=fl "1.0", v="about")) |
11 | RecognizedText(r=Rect(h=10, w=13, x=592, y=359), text=Scored(score=fl "0.9918628", v="to")) |
12 | RecognizedText(r=Rect(h=11, w=33, x=610, y=358), text=Scored(score=fl "0.998467", v="close")) |
13 | RecognizedText(r=Rect(h=10, w=6, x=648, y=359), text=Scored(score=fl "0.8560784", v="3")) |
14 | RecognizedText(r=Rect(h=11, w=31, x=659, y=358), text=Scored(score=fl "1.0", v="tabs.")) |
15 | RecognizedText(r=Rect(h=13, w=50, x=695, y=359), text=Scored(score=fl "0.9463429", v="Areyou")) |
16 | RecognizedText(r=Rect(h=10, w=33, x=812, y=359), text=Scored(score=fl "0.9773897", v="want")) |
17 | RecognizedText(r=Rect(h=10, w=13, x=850, y=359), text=Scored(score=fl "0.9918628", v="to")) |
18 | RecognizedText(r=Rect(h=11, w=65, x=868, y=358), text=Scored(score=fl "1.0", v="continue?")) |
19 | RecognizedText(r=Rect(h=8, w=20, x=523, y=361), text=Scored(score=fl "0.97618467", v="are")) |
20 | RecognizedText(r=Rect(h=8, w=28, x=751, y=361), text=Scored(score=fl "0.9821385", v="sure")) |
21 | RecognizedText(r=Rect(h=11, w=23, x=783, y=361), text=Scored(score=fl "0.9744504", v="you")) |
22 | RecognizedText(r=Rect(h=11, w=43, x=765, y=406), text=Scored(score=fl "0.99504626", v="Cancel"), clickTarget="Cancel") |
23 | RecognizedText(r=Rect(h=11, w=35, x=855, y=406), text=Scored(score=fl "1.0", v="Close"), clickTarget="Close tabs") |
24 | RecognizedText(r=Rect(h=11, w=28, x=895, y=406), text=Scored(score=fl "0.9762714", v="tabs"), clickTarget="Close tabs") |
25 | ]]; |
26 | |
27 | p { |
28 | L<RecognizedText> expected = map unstruct(tlft(data)); |
29 | |
30 | if (test) |
31 | selfTest(expected); |
32 | |
33 | if (real) { |
34 | print("\nLive mode!\n"); |
35 | mouseMover().endAfterInterference = false; |
36 | repeat with sleep 1 { |
37 | if (mouseMover().active2()) { |
38 | Pair<Double, Pt> p = recognize(expected, shootScreen2()); |
39 | if (p != null && p.a >= threshold) { |
40 | print("Found dialog at " + p.b); |
41 | L<Pt> targets = getClickTargets(expected, p.b).get("Cancel"); |
42 | mouseMover().moveMouse(oneOf(targets)); |
43 | } else print("No dialog found"); |
44 | } |
45 | } |
46 | } |
47 | } |
48 | |
49 | svoid selfTest(L<RecognizedText> expected) { |
50 | bool failures = false; |
51 | for (S imageID, Bool containsDialog : litorderedmap(#1101350, true, #1101351, true, #1101320, false)) { |
52 | Pair<Double, Pt> p = recognize(expected, loadImage2(imageID)); |
53 | print(containsDialog + " / " + p); |
54 | |
55 | bool found = p != null && p.a >= threshold; |
56 | if (containsDialog != found) { print("detection failure"); failures = true; } |
57 | else if (found) { |
58 | print("Found dialog correctly"); |
59 | //MultiMap<S, Pt> targets = getClickTargets(expected, p.b); |
60 | } |
61 | } |
62 | } |
63 | |
64 | static MultiMap<S, Pt> getClickTargets(L<RecognizedText> expected, Pt shift) { |
65 | new MultiMap<S, Pt> mm; |
66 | for (RecognizedText t : expected) { |
67 | S ct = getString(t, 'clickTarget); |
68 | if (ct != null) { |
69 | Pt pt = ptAdd(rectCenter(t.r), shift); |
70 | print("Click target: " + ct + " => " + pt); |
71 | mm.put(ct, pt); |
72 | } |
73 | } |
74 | ret mm; |
75 | } |
76 | |
77 | // returns (closeness, shift) |
78 | static Pair<Double, Pt> recognize(L<RecognizedText> expected, BufferedImage img) { |
79 | L<RecognizedText> actual = ocr_recognizeMultiLine_scored(img); |
80 | |
81 | MultiMap<S, RecognizedText> byWord = multiMapIndexOverMethod(actual, 'text); |
82 | |
83 | new Best<Pt> bestShift; |
84 | bestShift.put(pt(0, 0), tryShift(expected, byWord, pt(0, 0))); |
85 | |
86 | Map<Pt, Int> shifts = multiSetAsMap_popularFirst(possibleShifts(expected, byWord)); |
87 | //pnlStruct(shifts); |
88 | Pt shift = firstKey(shifts); |
89 | bestShift.put(shift, tryShift(expected, byWord, shift)); |
90 | ret best_reversedPair(bestShift); |
91 | } |
92 | |
93 | static MultiSet<Pt> possibleShifts(L<RecognizedText> expected, MultiMap<S, RecognizedText> byWord) { |
94 | new MultiSet<Pt> ms; |
95 | for (RecognizedText t : expected) { |
96 | L<RecognizedText> list = byWord.get(t.text()); |
97 | if (empty(list)) continue; |
98 | final Pt p = rectCenter(t.r); |
99 | for (RecognizedText r : list) |
100 | ms.add(ptDiff(rectCenter(r.r), p)); |
101 | } |
102 | ret ms; |
103 | } |
104 | |
105 | static double tryShift(L<RecognizedText> expected, MultiMap<S, RecognizedText> byWord, Pt shift) { |
106 | double closeness = 0; |
107 | for (RecognizedText t : expected) { |
108 | L<RecognizedText> list = byWord.get(t.text()); |
109 | //print(t.text() + " " + t.r + " => " + struct(collect('r, list))); |
110 | if (empty(list)) continue; |
111 | final Pt p = ptAdd(rectCenter(t.r), shift); |
112 | double dist = sqrt(minOfDoubles(map(list, func(RecognizedText r) { |
113 | ptDistanceSquared(p, rectCenter(r.r)) |
114 | }))); |
115 | closeness += 1/(dist+1); |
116 | //print(t.text() + " | dist=" + dist + ", c=" + closeness); |
117 | } |
118 | closeness /= l(expected); |
119 | //print("Closeness: " + closeness + " (" + l(expected) + ")"); |
120 | ret closeness; |
121 | } |
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, rbqtzklnwohg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1016916 |
Snippet name: | Recognize Firefox "Confirm close" dialog [works more or less] |
Eternal ID of this version: | #1016916/45 |
Text MD5: | 0121e401a63cbdfd09979f5433a2d0d9 |
Transpilation MD5: | 4f9a07ba3a9e145209a4b11a82c041e8 |
Author: | stefan |
Category: | javax / ocr |
Type: | JavaX source code (desktop) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-07-08 21:29:13 |
Source code size: | 5136 bytes / 121 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 587 / 1306 |
Version history: | 44 change(s) |
Referenced in: | [show references] |