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

110
LINES

< > BotCompany Repo | #1005840 // class AutoSegmenter

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (5300L/30K).

sclass AutoSegmenter {
  int g = 3;
  L<Rect> clips;
  bool[] grid;
  int gw, gh;
  bool diag; // merge diagonally too
  BWImage img;
  // contrastMethod2 = look at local contrast regardless of absolute brightness
  bool contrastMethod2 = true, blackBG;
  float contrastThreshold = 0.5f, brightnessThreshold = 0.5f;
  int overlap = 1;
  
  *() {}
  *(int *g) {}

  L<Rect> go(RGBImage img) { ret go(new BWImage(img)); }
  
  L<Rect> go(BWImage img) {
    this.img = img;
    int w = img.getWidth(), h = img.getHeight();
    gw = w/g;
    gh = h/g; // width & height of grid
    
    step1();
  
    new L<S> result;
    clips = new L;
  
    for (int y = 0; y < gh; y++)
      for (int x = 0; x < gw; x++)
        if (grid[y*gw+x]) {
          Rect r = fill(x, y);
          r = scaleRect(r, g);
          r = blackBG
            ? autoCropOfBWImage_blackBG(img, r, brightnessThreshold)
            : autoCropOfBWImage(img, r, brightnessThreshold);
          clips.add(r);
        }
      
    ret clips;
  }
  
  void step1() {
    int w = img.getWidth(), h = img.getHeight();
    grid = new bool[gw*gh];
  
    for (int gy = 0; gy <= h- g; gy += g)
      next: for (int gx = 0; gx <= w- g; gx += g) {
        float min = 1, max = 0;
        int y2 = min(h, gy + g + overlap);
        int x2 = min(w, gx + g + overlap);
        for (int y = gy; y < y2; y++)
          for (int x = gx; x < x2; x++) {
            float b = img.getPixel(x, y);
            min = Math.min(min, b);
            max = Math.max(max, b);
            if (contrastMethod2
              ? max-min >= contrastThreshold
              : min < brightnessThreshold && max > brightnessThreshold) {
              grid[(gy / g) * gw + (gx / g)] = true;
              continue next;
            }
          }
      }
  }

  // with virtual stack
  Rect fill(int x, int y) {
    Rect r = null;
    new L<Pt> stack;
    stack.add(new Pt(x, y));
    while (nempty(stack)) {
      Pt p = popLast(stack);
      x = p.x;
      y = p.y;

      if (!(x < 0 || y < 0 || x >= gw || y >= gh)) {
        int idx = y*gw+x;
        
        if (grid[idx]) {
          grid[idx] = false;
          Rect me = new Rect(x, y, 1, 1);
          if (r == null)
            r = me;
          else
            r = rectUnion(r, me);

          stack.add(new Pt(x-1, y));
          stack.add(new Pt(x+1, y));
          stack.add(new Pt(x, y-1));
          stack.add(new Pt(x, y+1));
        }
      }
    }
    ret r;
  }

  float visualizeGrid_darkening = 0.0f;
  
  BWImage visualizeGrid() {
    step1();
    BWImage im = new BWImage(img);
    for (int y = 0; y < gh; y++)
      for (int x = 0; x < gw; x++) {
        if (grid[y*gw+x]) continue;
        darkenBWImagePart(im, new Rect(x*g, y*g, g, g), visualizeGrid_darkening);
      }
    ret im;
  }
}

Author comment

Began life as a copy of #1005836

download  show line numbers  debug dex  old transpilations   

Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, sawdedvomwva, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1005840
Snippet name: class AutoSegmenter
Eternal ID of this version: #1005840/4
Text MD5: 67c85c8b56838955c855122659933a6d
Transpilation MD5: 1d8bbcb9de34e2955393be554968d38b
Author: stefan
Category: javax / ocr
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-05-15 02:49:43
Source code size: 2904 bytes / 110 lines
Pitched / IR pitched: No / No
Views / Downloads: 658 / 1648
Version history: 3 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)