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

85
LINES

< > BotCompany Repo | #1034925 // ZhangSuenThinner - binary image thinning algorithm [dev.]

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

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

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

srecord noeq ZhangSuenThinner(IBinaryImage image) {
  settable bool blackIsFG = true;
  
  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;
    int w = image.getWidth(), h = image.getHeight();

    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 image.getBoolPixel(x, y) != blackIsFG;
  }
  
  void clearPixel(int x, int y) {
    image.setPixel(x, y, blackIsFG);
  }
}

Author comment

Began life as a copy of #1034923

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1034925
Snippet name: ZhangSuenThinner - binary image thinning algorithm [dev.]
Eternal ID of this version: #1034925/9
Text MD5: ab3d2d6a3e28f4e4c25030192a5c6755
Transpilation MD5: c51f5018dce8febe7fffe749b3de823c
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:34:10
Source code size: 2133 bytes / 85 lines
Pitched / IR pitched: No / No
Views / Downloads: 158 / 259
Version history: 8 change(s)
Referenced in: [show references]