Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

225
LINES

< > BotCompany Repo | #1005522 // Persistent Image Finder [WORKS] - makes screenshot and searches for all known clips in them

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (8658L/59K/193K).

!752

concepts.

// Note: Don't reset idCounter in #1005389 if this program has
// imported data already.

!include #1005530 // PIF Classes (Clip, Found, FullySearched) + Screenshot + MarkedClip

static int searchBack = 5; // search back in how many screenshots (must be at least 1 to include current screenshot)

static float similarity = 0.999f;
static int maxCopiesPerClip = 100;
static int screenshotDelay = 3000;
static new LinkedBlockingDeque queue; // contains Screenshot or TRUE (stands for please cancel current job)
static JButton btnMark;
static JTextField tfDesc;
static JList list;

p {
  mainConcepts.useGZIP = true;
  mainConcepts.persist(30000);
  dbBot();
  
  importClips();
  
  /*for (Clip clip : mainConcepts.list(Clip)) {
    print("My Clip: " + clip.description);
  }*/

  if (countConcepts(Screenshot) == 0)
    new Screenshot(shootScreen2());
    
  awt {
    showControls(jCenteredLine(
      jbutton("New screenshot", "newScreenshot"),
      jbutton("Import new clips", "importClips")
    ));

    lowerPriorityThread("run"); // caveat: priorities don't work on Linux
    
    is = new ImageSurface {
      public void setSelection(Rectangle r) {
        super.setSelection(r);
        btnMark.setEnabled(r != null);
      }
    };
    
    /*is.addMouseMotionListener(new MouseAdapter {
      public void mouseMoved(MouseEvent e) {
        //is.setToolTipText(str(e.getPoint()));
      }
    });*/
    
    list = showRegularlyUpdatedList("Currently seen things", "makeList", 1000);
    addToWindowSplitRight(list, new JScrollPane(is));
    addToWindow(list, jcenteredLine(
      jMinWidth(300, onEnter(tfDesc = new JTextField, "mark")),
      btnMark = jdisabledButton("Mark", "mark")));
    tfDesc.requestFocus();
    moveToRightScreenEdge(getFrame(list));
    onDoubleClick(list, voidfunc(S item) {
      long foundID = parseFirstLong(item);
      Found found = cast getConcept(foundID);
      Rect r = found.fi.r;
      moveMouse(r.x+r.w/2, r.y+r.h/2);
    });
    
    // Make our own timer so it's not paused on pauseAll
    bindTimerToComponent(new Timer(250, actionListener {
      pcall {
        //print("calculating=" + calculating);
        consoleIcon_mem(allPaused() ? "#1005543"
          : calculating ? "#1005541" : null);
      }
    }), consoleFrame());
  }
}

static ImageSurface is;
static Screenshot lastShown;
static L<Rectangle> shownRects;

static L<S> makeList() {
  Screenshot screenshot = last(list(Screenshot));
  if (screenshot != lastShown) {
    is.setImage(loadImage2(screenshot.pngFile()));
    if (lastShown == null)
      is.zoomToDisplaySize();
    lastShown = screenshot;
  }

  new L<S> l;
  final L<Found> lFound = findBackRefs(screenshot, Found);
  for (Found found : lFound) pcall {
    l.add("[\* found.id */] \* found.clip->description */");
  }
  final L<Rectangle> rects = map(func(Found f) { f.fi.r.getRectangle() }, lFound);
  if (neq(shownRects, rects)) {
    shownRects = rects;
    is.overlay = voidfunc(Graphics2D g) {
      for (Rectangle r : rects)
        is.drawSelectionRect(g, r, Color.blue, Color.white);
    };
    is.repaint();
  }
  setFrameTitle(list, "Seeing " + n(l(l), "things"));
  ret l;
}

static volatile bool calculating;

svoid run {
  for (O o : grabFromQueueIterator(queue)) {
    if (o << Screenshot) {
      calculating = true;
      searchScreenshot(o/Screenshot);
      calculating = false;
    }
  }
}

svoid searchScreenshot(Screenshot screenshot) {
  print("Searching screenshot " + screenshot.id);
  BWImage screen = null;
  
  // Order clips by last found
  new LinkedHashSet<Clip> clips;
  for (Found found : reversed(list(Found)))
    addIfNotNull(clips, found.clip!);
  addAll(clips, reversed(list(Clip)));
  
  quickSearch(screenshot);
    
  for (Clip clip : clips) {
    if (queue.peekFirst() instanceof Bool) ret; // signal to canel
    if (findConcept(FullySearched, +screenshot, +clip) != null) continue;
    print("  Searching " + clip.description);
    if (screen == null)
      screen = new BWImage(loadImage2(screenshot.pngFile()));
    bwRawImageSearch_verbose = true;
    bwRawImageSearch_maxEntries = maxCopiesPerClip;
    for (FoundImg fi : bwRawImageSearch(screen, clip.img, similarity))
      uniq(Found, +screenshot, +clip, +fi);
    uniq(FullySearched, +screenshot, +clip);
  }
  print("Done searching screenshot");
}

svoid quickSearch(Screenshot screenshot) {
  new HashMap<Clip, Rect> lastPosition;
  for (Found found : reversed(list(Found)))
    if (!lastPosition.containsKey(found.clip!))
      lastPosition.put(found.clip!, found.fi.r);
  BWImage screen = null;
  for (Clip clip : keys(lastPosition)) pcall {
    if (findConcept(FullySearched, +screenshot, +clip) != null) continue;
    Rect pos = lastPosition.get(clip);
    print("  Quick-Searching " + clip.description + " at " + struct(pos));
    if (screen == null)
      screen = new BWImage(loadImage2(screenshot.pngFile()));
    BWImage pat = clip.img;
    int wp = pat.getWidth(), hp = pat.getHeight();
    float maxError = (1f-similarity)*wp*hp;
    float diff = bwImageSectionsSimilarity(screen, 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);
    }
  }
}

svoid importClips {
  Concepts inConcepts = new Concepts("#1005389").load();
  for (MarkedClip clip : inConcepts.list(MarkedClip)) {
    //print("Foreign Clip: " + clip.description);
    Clip cl = conceptWhere(Clip, originalID := clip.id);
    if (cl == null) {
      cl = cnew(Clip,
        originalID := clip.id,
        img := clip.img,
        description := clip.description);
      print(clip.description + " => Imported as " + cl.id);
    }
  }
  reScan();
}

svoid reScan {
  for (Screenshot s : takeLast(searchBack, list(Screenshot)))
    queue.addFirst(s);
  queue.addFirst(true); // signal to cancel current activity
}

svoid newScreenshot {
  consoleFrame().toBack();
  swingLater(screenshotDelay, r {
    Screenshot screenshot;
    queue.addFirst(screenshot = new Screenshot(shootScreen2()));
    Screenshot last = last(list(Screenshot));
    print("Screenshot id: " + screenshot.id + ", latest id: " + last.id);
    assertSame(screenshot, last);
    queue.addFirst(true); // signal to cancel current activity
    consoleFrame().toFront();
    getFrame(list).toFront();
  });
}

svoid mark {
  Rectangle r = is.getSelection();
  if (r == null) ret;
  
  S desc = tfDesc.getText().trim();
  cnew(MarkedClip, screenshot := lastShown,
    positionInScreenshot := new Rect(r),
    img := new BWImage(is.getImage()).clip(r),
    description := desc);
  showAnimation("#1005392", quote(desc), 1);
  print("Marked clip! " + quote(desc) + " (" + r + ")");
  tfDesc.selectAll();
  tfDesc.requestFocus();
  reScan();
}

Author comment

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: 851 / 2088
Referenced in: #1005265 - Show concepts of a program in tabs [works]
#1005530 - PIF [Persistent Image Finder] Classes
#1005531 - PIF Reasoning 1 [Clustering, works, but might not be accurate if not every clip was searched in every screenshot]
#1005533 - Show PIF clips DB [works]
#1005562 - PIF Reasoning 2 [Clip positions, WORKS]
#1005601 - Bench loading loads of concepts without classes [now really fast]
#1005684 - class ImageFinder
#1005775 - Connect to PIF DB