// Note: requires e.g. #1005530 - PIF Classes (Clip, Found, FullySearched, Screenshot) sclass ImageFinder { L screenshots = synchroList(); L clips = synchroList(); float similarity = 0.999f; int maxCopiesPerClip = 100; Int maxTotal; // max total clips found per screenshot //new LinkedBlockingDeque queue; bool quickSearch_clipBufferedImage = true; bool fullSearch = true; *() {} *(L *screenshots, L *clips) {} *(Screenshot screenshot, L clips) { this(ll(screenshot), clips); } void run() { for (Screenshot s : cloneList(screenshots)) searchScreenshot(s); } void searchScreenshot(Screenshot screenshot) { print("Searching screenshot " + screenshot.id); new Var screen; // Order clips by last found /*new LinkedHashSet clips; for (Found found : reversed(list(Found))) addIfNotNull(clips, found.clip!); addAll(clips, reversed(list(Clip)));*/ quickSearch(screenshot, screen); if (fullSearch && !foundEnough(screenshot)) it: for (Clip clip : clips) { if (findConcept(FullySearched, +screenshot, +clip) != null) continue; print(" Searching " + clip.description); if (!screenshot.hasImage()) continue; if (!screen.has()) screen.set(new BWImage(screenshot.loadImage())); bwRawImageSearch_verbose = true; bwRawImageSearch_maxEntries = maxCopiesPerClip; for (FoundImg fi : bwRawImageSearch(screen.v, clip.img, similarity)) { uniq(Found, +screenshot, +clip, +fi); if (foundEnough(screenshot)) break it; } uniq(FullySearched, +screenshot, +clip); } print("Done " + (fullSearch ? "" : "quick-") + "searching screenshot"); } void quickSearch(Screenshot screenshot, Var screen) { new HashMap lastPosition; for (Found found : reversed(list(Found))) if (!lastPosition.containsKey(found.clip!)) lastPosition.put(found.clip!, found.fi.r); for (Clip clip : keys(lastPosition)) pcall { if (!clips.contains(clip)) continue; if (findConcept(FullySearched, +screenshot, +clip) != null) continue; Rect pos = lastPosition.get(clip); print(" Quick-Searching " + clip.description + " at " + struct(pos)); BWImage pat = clip.img; int wp = pat.getWidth(), hp = pat.getHeight(); float maxError = (1f-similarity)*wp*hp; float diff; if (quickSearch_clipBufferedImage) { // TODO: cache image BWImage big = new BWImage(clipBufferedImage(screenshot.loadImage(), new Rectangle(pos.x, pos.y, wp, hp))); diff = bwImageSectionsSimilarity(big, pat, 0, 0, maxError); } else { if (!screen.has()) screen.set(new BWImage(screenshot.loadImage())); diff = bwImageSectionsSimilarity(screen.v, pat, pos.x, pos.y, maxError); } if (diff <= maxError) { float sim = 1-diff/(wp*hp); FoundImg fi = new FoundImg(pos, sim); print(" Found!"); uniq(Found, +screenshot, +clip, +fi); if (foundEnough(screenshot)) break; } } } bool foundEnough(Screenshot screenshot) { ret maxTotal != null && l(findBackRefs(screenshot, Found)) >= maxTotal; } }