DOWNLOAD
package Skeleton; import ij.ImageStack;import java.util.ArrayList;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveTask; public class ForkJoinSkeletonize2 extends RecursiveTask<ArrayList<int[]>> { private int mLength; private int mStart; private int sThreshold = 250; private int depth = 1; private int width; private int height; private ImageStack outputImage; private ImageStack src; private int[] eulerLUT = new int[256]; private int currentBorder; private ArrayList<int[]> mSimpleBorderPoints; public ForkJoinSkeletonize2(ImageStack src, int start, int length, int currentBorder, int[] eulerLUT) { this.src = src; this.outputImage = src; this.width = src.getWidth(); this.height = src.getHeight(); this.mStart = start; this.mLength = length; this.currentBorder = currentBorder; this.mSimpleBorderPoints = new ArrayList<>(); this.eulerLUT = eulerLUT; } ForkJoinSkeletonize2() { } public ArrayList<int[]> computeDirectly() { for(int z = 0; z < this.depth; ++z) { for(int y = 0; y < this.height; ++y) { for(int x = this.mStart; x < this.mStart + this.mLength; ++x) { if (SUM.getPixel(this.outputImage, x, y, z) == 1) { boolean isBorderPoint = false; if (this.currentBorder == 1 && SUM.N(this.outputImage, x, y, z) <= 0) { isBorderPoint = true; } if (this.currentBorder == 2 && SUM.S(this.outputImage, x, y, z) <= 0) { isBorderPoint = true; } if (this.currentBorder == 3 && SUM.E(this.outputImage, x, y, z) <= 0) { isBorderPoint = true; } if (this.currentBorder == 4 && SUM.W(this.outputImage, x, y, z) <= 0) { isBorderPoint = true; } if (this.currentBorder == 5 && SUM.U(this.outputImage, x, y, z) <= 0) { isBorderPoint = true; } if (this.currentBorder == 6 && SUM.B(this.outputImage, x, y, z) <= 0) { isBorderPoint = true; } if (isBorderPoint) { int numberOfNeighbors = -1; byte[] neighbor = SUM.getNeighborhood(this.outputImage, x, y, z); for(int i = 0; i < 27; ++i) { if (neighbor[i] == 1) { ++numberOfNeighbors; } } if (numberOfNeighbors != 1 && SUM.isEulerInvariant(neighbor, this.eulerLUT) && SUM.isSimplePoint(neighbor)) { int[] index = new int[]{x, y, z}; this.mSimpleBorderPoints.add(index); } } } } } } return this.mSimpleBorderPoints; } protected ArrayList<int[]> compute() { if (this.mLength < this.sThreshold) { return this.computeDirectly(); } else { int split = this.mLength / 2; int remainder = this.mLength % 2; int secondHalf = split + remainder; ForkJoinSkeletonize2 left = new ForkJoinSkeletonize2(this.src, this.mStart, split, this.currentBorder, this.eulerLUT); ForkJoinSkeletonize2 right = new ForkJoinSkeletonize2(this.src, this.mStart + split, secondHalf, this.currentBorder, this.eulerLUT); right.fork(); ArrayList<int[]> a = left.compute(); a.addAll(right.join()); return a; } } public ArrayList<int[]> thin(ImageStack src, int currentBorder, int[] eulerLUT) { new ArrayList(); this.outputImage = src; ForkJoinSkeletonize2 fe = new ForkJoinSkeletonize2(this.outputImage, 0, this.outputImage.getWidth(), currentBorder, eulerLUT); ForkJoinPool pool = new ForkJoinPool(); return pool.invoke(fe); }}