DOWNLOAD
package Algorithms; import Utils.*;import java.util.Arrays;import java.util.concurrent.ExecutionException; public class VesselThickness{ public static double computeMedianVesselThickness( ISliceRunner runner, int maxWorkers, int[] points, int arraySize, int pointSize, int[] scratch, byte[] input, int width, int height ) throws ExecutionException { final int nPoints = arraySize / pointSize; if (nPoints <= 0) return 0.0; final int thresh = 200; runner.runSlices(new Step1(scratch, input, width, height, thresh), maxWorkers, height, (height / 4) + 1); double[] vesselThickness = DoubleBufferPool.acquireAsIs(nPoints); final int maxDimension = Math.max(width, height); final int maxResult = 3 * (maxDimension + 1) * (maxDimension + 1); for(int i = 0; i < nPoints; i++) { int x = points[i*pointSize]; int y1 = points[i*pointSize + 1]; if ((input[x + width * y1] & 255) < thresh) { vesselThickness[i] = 0.0; continue; } int min = maxResult; // the X and Y of 'scratch' were flipped in step 1 for (int y2 = 0; y2 < height; ++y2) min = Math.min(scratch[y2 + height * x] + (y1-y2)*(y1-y2), min); double result = Math.sqrt(min); vesselThickness[i] = result; } Arrays.sort(vesselThickness, 0, nPoints); int middle = nPoints / 2; double thickness = nPoints % 2 == 1 ? vesselThickness[middle] : (vesselThickness[middle - 1] + vesselThickness[middle]) / 2.0; DoubleBufferPool.release(vesselThickness); return thickness * 2.0; } static class Step1 implements ISliceCompute { final int[] output; final byte[] input; final int width; final int height; final int thresh; public Step1(int[] output, byte[] input, int width, int height, int thresh) { this.output = output; this.input = input; this.width = width; this.height = height; this.thresh = thresh; } @Override public void initSlices(int nSlices) {} @Override public Object computeSlice(int sliceIdx, int start, int length) { final int maxDimension = Math.max(width, height); final int maxResult = 3 * (maxDimension + 1) * (maxDimension + 1); for (int j = start; j < start + length; j++) { for (int i = 0; i < width; ++i) { int min = maxResult; for (int x = i; x < width; ++x) { if ((input[x + width * j] & 255) < thresh) { min = (i-x)*(i-x); break; } } for(int x = i - 1; x >= 0; --x) { if ((input[x + width * j] & 255) < thresh) { min = Math.min((i-x)*(i-x), min); break; } } // swap X and Y to improve memory locality in the next step output[j + height * i] = min; } } return null; } @Override public void finishSlice(ISliceCompute.Result res) {} }}