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: | 883 / 1874 |
| Version history: | 44 change(s) |
| Referenced in: | [show references] |