Libraryless. Click here for Pure Java version (8658L/59K/193K).
1 | !752 |
2 | |
3 | concepts. |
4 | |
5 | // Note: Don't reset idCounter in #1005389 if this program has |
6 | // imported data already. |
7 | |
8 | !include #1005530 // PIF Classes (Clip, Found, FullySearched) + Screenshot + MarkedClip |
9 | |
10 | static int searchBack = 5; // search back in how many screenshots (must be at least 1 to include current screenshot) |
11 | |
12 | static float similarity = 0.999f; |
13 | static int maxCopiesPerClip = 100; |
14 | static int screenshotDelay = 3000; |
15 | static new LinkedBlockingDeque queue; // contains Screenshot or TRUE (stands for please cancel current job) |
16 | static JButton btnMark; |
17 | static JTextField tfDesc; |
18 | static JList list; |
19 | |
20 | p { |
21 | mainConcepts.useGZIP = true; |
22 | mainConcepts.persist(30000); |
23 | dbBot(); |
24 | |
25 | importClips(); |
26 | |
27 | /*for (Clip clip : mainConcepts.list(Clip)) { |
28 | print("My Clip: " + clip.description); |
29 | }*/ |
30 | |
31 | if (countConcepts(Screenshot) == 0) |
32 | new Screenshot(shootScreen2()); |
33 | |
34 | awt { |
35 | showControls(jCenteredLine( |
36 | jbutton("New screenshot", "newScreenshot"), |
37 | jbutton("Import new clips", "importClips") |
38 | )); |
39 | |
40 | lowerPriorityThread("run"); // caveat: priorities don't work on Linux |
41 | |
42 | is = new ImageSurface { |
43 | public void setSelection(Rectangle r) { |
44 | super.setSelection(r); |
45 | btnMark.setEnabled(r != null); |
46 | } |
47 | }; |
48 | |
49 | /*is.addMouseMotionListener(new MouseAdapter { |
50 | public void mouseMoved(MouseEvent e) { |
51 | //is.setToolTipText(str(e.getPoint())); |
52 | } |
53 | });*/ |
54 | |
55 | list = showRegularlyUpdatedList("Currently seen things", "makeList", 1000); |
56 | addToWindowSplitRight(list, new JScrollPane(is)); |
57 | addToWindow(list, jcenteredLine( |
58 | jMinWidth(300, onEnter(tfDesc = new JTextField, "mark")), |
59 | btnMark = jdisabledButton("Mark", "mark"))); |
60 | tfDesc.requestFocus(); |
61 | moveToRightScreenEdge(getFrame(list)); |
62 | onDoubleClick(list, voidfunc(S item) { |
63 | long foundID = parseFirstLong(item); |
64 | Found found = cast getConcept(foundID); |
65 | Rect r = found.fi.r; |
66 | moveMouse(r.x+r.w/2, r.y+r.h/2); |
67 | }); |
68 | |
69 | // Make our own timer so it's not paused on pauseAll |
70 | bindTimerToComponent(new Timer(250, actionListener { |
71 | pcall { |
72 | //print("calculating=" + calculating); |
73 | consoleIcon_mem(allPaused() ? "#1005543" |
74 | : calculating ? "#1005541" : null); |
75 | } |
76 | }), consoleFrame()); |
77 | } |
78 | } |
79 | |
80 | static ImageSurface is; |
81 | static Screenshot lastShown; |
82 | static L<Rectangle> shownRects; |
83 | |
84 | static L<S> makeList() { |
85 | Screenshot screenshot = last(list(Screenshot)); |
86 | if (screenshot != lastShown) { |
87 | is.setImage(loadImage2(screenshot.pngFile())); |
88 | if (lastShown == null) |
89 | is.zoomToDisplaySize(); |
90 | lastShown = screenshot; |
91 | } |
92 | |
93 | new L<S> l; |
94 | final L<Found> lFound = findBackRefs(screenshot, Found); |
95 | for (Found found : lFound) pcall { |
96 | l.add("[\* found.id */] \* found.clip->description */"); |
97 | } |
98 | final L<Rectangle> rects = map(func(Found f) { f.fi.r.getRectangle() }, lFound); |
99 | if (neq(shownRects, rects)) { |
100 | shownRects = rects; |
101 | is.overlay = voidfunc(Graphics2D g) { |
102 | for (Rectangle r : rects) |
103 | is.drawSelectionRect(g, r, Color.blue, Color.white); |
104 | }; |
105 | is.repaint(); |
106 | } |
107 | setFrameTitle(list, "Seeing " + n(l(l), "things")); |
108 | ret l; |
109 | } |
110 | |
111 | static volatile bool calculating; |
112 | |
113 | svoid run { |
114 | for (O o : grabFromQueueIterator(queue)) { |
115 | if (o << Screenshot) { |
116 | calculating = true; |
117 | searchScreenshot(o/Screenshot); |
118 | calculating = false; |
119 | } |
120 | } |
121 | } |
122 | |
123 | svoid searchScreenshot(Screenshot screenshot) { |
124 | print("Searching screenshot " + screenshot.id); |
125 | BWImage screen = null; |
126 | |
127 | // Order clips by last found |
128 | new LinkedHashSet<Clip> clips; |
129 | for (Found found : reversed(list(Found))) |
130 | addIfNotNull(clips, found.clip!); |
131 | addAll(clips, reversed(list(Clip))); |
132 | |
133 | quickSearch(screenshot); |
134 | |
135 | for (Clip clip : clips) { |
136 | if (queue.peekFirst() instanceof Bool) ret; // signal to canel |
137 | if (findConcept(FullySearched, +screenshot, +clip) != null) continue; |
138 | print(" Searching " + clip.description); |
139 | if (screen == null) |
140 | screen = new BWImage(loadImage2(screenshot.pngFile())); |
141 | bwRawImageSearch_verbose = true; |
142 | bwRawImageSearch_maxEntries = maxCopiesPerClip; |
143 | for (FoundImg fi : bwRawImageSearch(screen, clip.img, similarity)) |
144 | uniq(Found, +screenshot, +clip, +fi); |
145 | uniq(FullySearched, +screenshot, +clip); |
146 | } |
147 | print("Done searching screenshot"); |
148 | } |
149 | |
150 | svoid quickSearch(Screenshot screenshot) { |
151 | new HashMap<Clip, Rect> lastPosition; |
152 | for (Found found : reversed(list(Found))) |
153 | if (!lastPosition.containsKey(found.clip!)) |
154 | lastPosition.put(found.clip!, found.fi.r); |
155 | BWImage screen = null; |
156 | for (Clip clip : keys(lastPosition)) pcall { |
157 | if (findConcept(FullySearched, +screenshot, +clip) != null) continue; |
158 | Rect pos = lastPosition.get(clip); |
159 | print(" Quick-Searching " + clip.description + " at " + struct(pos)); |
160 | if (screen == null) |
161 | screen = new BWImage(loadImage2(screenshot.pngFile())); |
162 | BWImage pat = clip.img; |
163 | int wp = pat.getWidth(), hp = pat.getHeight(); |
164 | float maxError = (1f-similarity)*wp*hp; |
165 | float diff = bwImageSectionsSimilarity(screen, pat, pos.x, pos.y, maxError); |
166 | if (diff <= maxError) { |
167 | float sim = 1-diff/(wp*hp); |
168 | FoundImg fi = new FoundImg(pos, sim); |
169 | print(" Found!"); |
170 | uniq(Found, +screenshot, +clip, +fi); |
171 | } |
172 | } |
173 | } |
174 | |
175 | svoid importClips { |
176 | Concepts inConcepts = new Concepts("#1005389").load(); |
177 | for (MarkedClip clip : inConcepts.list(MarkedClip)) { |
178 | //print("Foreign Clip: " + clip.description); |
179 | Clip cl = conceptWhere(Clip, originalID := clip.id); |
180 | if (cl == null) { |
181 | cl = cnew(Clip, |
182 | originalID := clip.id, |
183 | img := clip.img, |
184 | description := clip.description); |
185 | print(clip.description + " => Imported as " + cl.id); |
186 | } |
187 | } |
188 | reScan(); |
189 | } |
190 | |
191 | svoid reScan { |
192 | for (Screenshot s : takeLast(searchBack, list(Screenshot))) |
193 | queue.addFirst(s); |
194 | queue.addFirst(true); // signal to cancel current activity |
195 | } |
196 | |
197 | svoid newScreenshot { |
198 | consoleFrame().toBack(); |
199 | swingLater(screenshotDelay, r { |
200 | Screenshot screenshot; |
201 | queue.addFirst(screenshot = new Screenshot(shootScreen2())); |
202 | Screenshot last = last(list(Screenshot)); |
203 | print("Screenshot id: " + screenshot.id + ", latest id: " + last.id); |
204 | assertSame(screenshot, last); |
205 | queue.addFirst(true); // signal to cancel current activity |
206 | consoleFrame().toFront(); |
207 | getFrame(list).toFront(); |
208 | }); |
209 | } |
210 | |
211 | svoid mark { |
212 | Rectangle r = is.getSelection(); |
213 | if (r == null) ret; |
214 | |
215 | S desc = tfDesc.getText().trim(); |
216 | cnew(MarkedClip, screenshot := lastShown, |
217 | positionInScreenshot := new Rect(r), |
218 | img := new BWImage(is.getImage()).clip(r), |
219 | description := desc); |
220 | showAnimation("#1005392", quote(desc), 1); |
221 | print("Marked clip! " + quote(desc) + " (" + r + ")"); |
222 | tfDesc.selectAll(); |
223 | tfDesc.requestFocus(); |
224 | reScan(); |
225 | } |
Began life as a copy of #1005395
download show line numbers debug dex old transpilations
Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, sawdedvomwva, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1005522 |
Snippet name: | Persistent Image Finder [WORKS] - makes screenshot and searches for all known clips in them |
Eternal ID of this version: | #1005522/1 |
Text MD5: | 2d1dbdcc7dcc395db39c7beb19aa006f |
Transpilation MD5: | 859997b55390a72d6af26350dc89a22b |
Author: | stefan |
Category: | javax / ocr |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-12-08 14:52:09 |
Source code size: | 7058 bytes / 225 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 852 / 2089 |
Referenced in: | [show references] |