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

83
LINES

< > BotCompany Repo | #1034927 // ZhangSuenThinner_byteArray

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

Libraryless. Click here for Pure Java version (5635L/31K).

// from https://rosettacode.org/wiki/Zhang-Suen_thinning_algorithm#Java

// each array element is one pixel (0 = background, anything else = foreground)
srecord noeq ZhangSuenThinner_byteArray(int w, int h, byte[] pixels) {
  static final int[][] nbrs = {{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1},
    {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}};
 
  static final int[][][] nbrGroups = {
    {{0, 2, 4}, {2, 4, 6}},
    {{0, 2, 6}, {0, 4, 6}}};
 
  new PtBuffer toWhite;

  run {
    bool firstStep;

    while ping (true) {
      firstStep = !firstStep;

      for (int r = 1; r < h - 1; r++)
        for (int c = 1; c < w - 1; c++) {
          if (!getPixel(c, r))
            continue;

          int nn = numNeighbors(r, c);
          if (nn < 2 || nn > 6)
            continue;

          if (numTransitions(r, c) != 1)
            continue;

          if (!atLeastOneIsWhite(r, c, firstStep ? 0 : 1))
            continue;

          toWhite.add(c, r);
        }

      if (!firstStep && empty(toWhite)) break;
      for (Pt p : toWhite)
        clearPixel(p.x, p.y);
      toWhite.clear();
    }
  }

  int numNeighbors(int r, int c) {
    int count = 0;
    for (int i = 0; i < nbrs.length - 1; i++)
      if (getPixel(c + nbrs[i][0], r + nbrs[i][1]))
        count++;
    ret count;
  }

  int numTransitions(int r, int c) {
    int count = 0;
    for (int i = 0; i < nbrs.length - 1; i++)
      if (!getPixel(c + nbrs[i][0], r + nbrs[i][1])
        && getPixel(c + nbrs[i+1][0], r + nbrs[i+1][1]))
          count++;
    ret count;
  }

  bool atLeastOneIsWhite(int r, int c, int step) {
    int count = 0;
    int[][] group = nbrGroups[step];
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < group[i].length; j++) {
        int[] nbr = nbrs[group[i][j]];
        if (!getPixel(c + nbr[0], r + nbr[1])) {
          count++;
          break;
        }
      }
    ret count > 1;
  }
  
  bool getPixel(int x, int y) {
    ret pixels[y*w+x] != 0;
  }
  
  void clearPixel(int x, int y) {
    pixels[y*w+x] = 0;
  }
}

Author comment

Began life as a copy of #1034925

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1034927
Snippet name: ZhangSuenThinner_byteArray
Eternal ID of this version: #1034927/4
Text MD5: a305bc2cf79b9f765ee8f4c2f09c0306
Transpilation MD5: 8d18fef3ed5ef2c9b0e93c83cadbdca3
Author: stefan
Category: javax / imaging
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-03-15 20:49:11
Source code size: 2107 bytes / 83 lines
Pitched / IR pitched: No / No
Views / Downloads: 178 / 241
Version history: 3 change(s)
Referenced in: [show references]