public static int[] findMaxima(double[] xx, double tolerance, boolean excludeOnEdges) { int edgeBehavior = (excludeOnEdges) ? 1 : 0; return findMaxima(xx, tolerance, edgeBehavior); }
/** * Returns minimum positions of array xx, sorted with decreasing strength */ public static int[] findMinima(double[] xx, double tolerance, boolean excludeEdges ) { int edgeMode = (excludeEdges) ? 1 : 0; return findMinima(xx, tolerance, edgeMode); }
if (dirOffset == null) makeDirectionOffsets(ip); Rectangle roi = ip.getRoi(); byte[] mask = ip.getMaskArray(); long[] maxPoints = getSortedMaxPoints(ip, typeP, excludeEdgesNow, isEDM, globalMin, globalMax, threshold); if (Thread.currentThread().isInterrupted()) return null; IJ.showStatus("Analyzing maxima..."); if (ip instanceof FloatProcessor) //sorted sequence may be inaccurate by this value maxSortingError = 1.1f * (isEDM ? SQRT2/2f : (globalMax-globalMin)/2e9f); analyzeAndMarkMaxima(ip, typeP, maxPoints, excludeEdgesNow, isEDM, globalMin, tolerance, outputType, maxSortingError); outIp = make8bit(ip, typeP, isEDM, globalMin, globalMax, threshold); cleanupMaxima(outIp, typeP, maxPoints); //eliminate all the small maxima (i.e. those outside MAX_AREA) if (!watershedSegment(outIp)) //do watershed segmentation return null; //if user-cancelled, return if (!isEDM) cleanupExtraLines(outIp); //eliminate lines due to local minima (none in EDM) watershedPostProcess(outIp); //levels to binary image if (excludeOnEdges) deleteEdgeParticles(outIp, typeP); } else { //outputType other than SEGMENTED for (int i=0; i<width*height; i++)
int[] table = makeFateTable(); IJ.showStatus("Segmenting (Esc to cancel)"); final int[] directionSequence = new int[] {7, 3, 1, 5, 0, 4, 2, 6}; // diagonal directions first int dIndex = 0; do { // expand each level in 8 directions int n = processLevel(directionSequence[dIndex%8], ip, table, levelStart[level], remaining, coordinates, setPointList); dIndex++; } while (remaining>0 && idle++<8); addProgress(sumN/(double)arraySize); if (IJ.escapePressed()) { // cancelled by the user IJ.beep(); addToNext = true; //image border else for (int d=0; d<8; d++) if (isWithin(x, y, d) && pixels[pOffset+dirOffset[d]]==0) { addToNext = true; //border of area below threshold break;
public double getDiamaterMaximumInscribedCircle() { ImagePlus help = generateBlobImage(this); ImageProcessor ipHelp = help.getProcessor(); ipHelp.invert(); EDM dm = new EDM(); FloatProcessor fp = dm.makeFloatEDM (ipHelp, 0, false); MaximumFinder mf = new MaximumFinder(); ByteProcessor bp = mf.findMaxima(fp, 0.5, ImageProcessor.NO_THRESHOLD, MaximumFinder.SINGLE_POINTS, false, true); Polygon pl = mf.getMaxima(bp, 0, true); return fp.getf(pl.xpoints[0], pl.ypoints[0])*2*cal.getX(1); }
Variable[] findArrayMaxima(boolean minima) { int edgeMode = 0; interp.getLeftParen(); Variable[] a = getArray(); double tolerance = getNextArg(); if (interp.nextToken()==',') { interp.getComma(); edgeMode = (int)interp.getExpression(); } interp.getRightParen(); int n = a.length; double[] d = new double[n]; for (int i=0; i<n; i++) d[i] = a[i].getValue(); int[] maxima = null; if (minima) maxima = MaximumFinder.findMinima(d, tolerance, edgeMode); else maxima = MaximumFinder.findMaxima(d, tolerance, edgeMode); int n2 = maxima.length; Variable[] a2 = new Variable[n2]; for (int i=0; i<n2; i++) a2[i] = new Variable(maxima[i]); return a2; }
/** delete particles corresponding to edge maxima * @param typeP Here the pixel types of the original image are noted, * pixels with bit MAX_AREA at the edge are considered indicators of an edge maximum. * @param ip the image resulting from watershed segmentaiton * (foreground pixels, i.e. particles, are 255, background 0) */ void deleteEdgeParticles(ByteProcessor ip, ByteProcessor typeP) { byte[] pixels = (byte[])ip.getPixels(); byte[] types = (byte[])typeP.getPixels(); width = ip.getWidth(); height = ip.getHeight(); ip.setValue(0); Wand wand = new Wand(ip); for (int x=0; x<width; x++) { int y = 0; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); y = height - 1; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); } for (int y=1; y<height-1; y++) { int x = 0; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); x = width - 1; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); } } //void deleteEdgeParticles
public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) { ImageProcessor ip = imp.getProcessor(); ip.resetBinaryThreshold(); // remove any invisible threshold set by Make Binary or Convert to Mask thresholded = ip.getMinThreshold()!=ImageProcessor.NO_THRESHOLD; GenericDialog gd = new GenericDialog(command); int digits = (ip instanceof FloatProcessor)?2:0; String unit = (imp.getCalibration()!=null)?imp.getCalibration().getValueUnit():null; unit = (unit==null||unit.equals("Gray Value"))?":":" ("+unit+"):"; gd.addNumericField("Noise tolerance"+unit,tolerance, digits); gd.addChoice("Output type:", outputTypeNames, outputTypeNames[dialogOutputType]); gd.addCheckbox("Exclude edge maxima", excludeOnEdges); if (thresholded) gd.addCheckbox("Above lower threshold", useMinThreshold); gd.addCheckbox("Light background", lightBackground); gd.addPreviewCheckbox(pfr, "Preview point selection"); gd.addMessage(" "); //space for number of maxima messageArea = (Label)gd.getMessage(); gd.addDialogListener(this); checkboxes = gd.getCheckboxes(); previewing = true; gd.addHelp(IJ.URL+"/docs/menus/process.html#find-maxima"); gd.showDialog(); //input by the user (or macro) happens here if (gd.wasCanceled()) return DONE; previewing = false; if (!dialogItemChanged(gd, null)) //read parameters return DONE; IJ.register(this.getClass()); //protect static class variables (parameters) from garbage collection return flags; } // boolean showDialog
if (dirOffset == null) makeDirectionOffsets(ip); Rectangle roi = ip.getRoi(); byte[] mask = ip.getMaskArray(); long[] maxPoints = getSortedMaxPoints(ip, typeP, excludeEdgesNow, isEDM, globalMin, globalMax, threshold); if (Thread.currentThread().isInterrupted()) return null; IJ.showStatus("Analyzing maxima..."); if (ip instanceof FloatProcessor) //sorted sequence may be inaccurate by this value maxSortingError = 1.1f * (isEDM ? SQRT2/2f : (globalMax-globalMin)/2e9f); analyzeAndMarkMaxima(ip, typeP, maxPoints, excludeEdgesNow, isEDM, globalMin, tolerance, outputType, maxSortingError); outIp = make8bit(ip, typeP, isEDM, globalMin, globalMax, threshold); cleanupMaxima(outIp, typeP, maxPoints); //eliminate all the small maxima (i.e. those outside MAX_AREA) if (!watershedSegment(outIp)) //do watershed segmentation return null; //if user-cancelled, return if (!isEDM) cleanupExtraLines(outIp); //eliminate lines due to local minima (none in EDM) watershedPostProcess(outIp); //levels to binary image if (excludeOnEdges) deleteEdgeParticles(outIp, typeP); } else { //outputType other than SEGMENTED for (int i=0; i<width*height; i++)
int[] table = makeFateTable(); IJ.showStatus("Segmenting (Esc to cancel)"); final int[] directionSequence = new int[] {7, 3, 1, 5, 0, 4, 2, 6}; // diagonal directions first int dIndex = 0; do { // expand each level in 8 directions int n = processLevel(directionSequence[dIndex%8], ip, table, levelStart[level], remaining, coordinates, setPointList); dIndex++; } while (remaining>0 && idle++<8); addProgress(sumN/(double)arraySize); if (IJ.escapePressed()) { // cancelled by the user IJ.beep(); addToNext = true; //image border else for (int d=0; d<8; d++) if (isWithin(x, y, d) && pixels[pOffset+dirOffset[d]]==0) { addToNext = true; //border of area below threshold break;
Variable[] findArrayMaxima(boolean minima) { int edgeMode = 0; interp.getLeftParen(); Variable[] a = getArray(); double tolerance = getNextArg(); if (interp.nextToken()==',') { interp.getComma(); edgeMode = (int)interp.getExpression(); } interp.getRightParen(); int n = a.length; double[] d = new double[n]; for (int i=0; i<n; i++) d[i] = a[i].getValue(); int[] maxima = null; if (minima) maxima = MaximumFinder.findMinima(d, tolerance, edgeMode); else maxima = MaximumFinder.findMaxima(d, tolerance, edgeMode); int n2 = maxima.length; Variable[] a2 = new Variable[n2]; for (int i=0; i<n2; i++) a2[i] = new Variable(maxima[i]); return a2; }
/** delete particles corresponding to edge maxima * @param typeP Here the pixel types of the original image are noted, * pixels with bit MAX_AREA at the edge are considered indicators of an edge maximum. * @param ip the image resulting from watershed segmentaiton * (foreground pixels, i.e. particles, are 255, background 0) */ void deleteEdgeParticles(ByteProcessor ip, ByteProcessor typeP) { byte[] pixels = (byte[])ip.getPixels(); byte[] types = (byte[])typeP.getPixels(); width = ip.getWidth(); height = ip.getHeight(); ip.setValue(0); Wand wand = new Wand(ip); for (int x=0; x<width; x++) { int y = 0; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); y = height - 1; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); } for (int y=1; y<height-1; y++) { int x = 0; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); x = width - 1; if ((types[x+y*width]&MAX_AREA) != 0 && pixels[x+y*width] != 0) deleteParticle(x,y,ip,wand); } } //void deleteEdgeParticles
public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) { ImageProcessor ip = imp.getProcessor(); ip.resetBinaryThreshold(); // remove any invisible threshold set by Make Binary or Convert to Mask thresholded = ip.getMinThreshold()!=ImageProcessor.NO_THRESHOLD; GenericDialog gd = new GenericDialog(command); int digits = (ip instanceof FloatProcessor)?2:0; String unit = (imp.getCalibration()!=null)?imp.getCalibration().getValueUnit():null; unit = (unit==null||unit.equals("Gray Value"))?":":" ("+unit+"):"; gd.addNumericField("Noise tolerance"+unit,tolerance, digits); gd.addChoice("Output type:", outputTypeNames, outputTypeNames[dialogOutputType]); gd.addCheckbox("Exclude edge maxima", excludeOnEdges); if (thresholded) gd.addCheckbox("Above lower threshold", useMinThreshold); gd.addCheckbox("Light background", lightBackground); gd.addPreviewCheckbox(pfr, "Preview point selection"); gd.addMessage(" "); //space for number of maxima messageArea = (Label)gd.getMessage(); gd.addDialogListener(this); checkboxes = gd.getCheckboxes(); previewing = true; gd.addHelp(IJ.URL+"/docs/menus/process.html#find-maxima"); gd.showDialog(); //input by the user (or macro) happens here if (gd.wasCanceled()) return DONE; previewing = false; if (!dialogItemChanged(gd, null)) //read parameters return DONE; IJ.register(this.getClass()); //protect static class variables (parameters) from garbage collection return flags; } // boolean showDialog
public static int[] findMinima(double[] xx, double tolerance, int edgeMode) { int len = xx.length; double[] negArr = new double[len]; for (int jj = 0; jj < len; jj++) negArr[jj] = -xx[jj]; int[] minPositions = findMaxima(negArr, tolerance, edgeMode); return minPositions; }
/** * Returns minimum positions of array xx, sorted with decreasing strength */ public static int[] findMinima(double[] xx, double tolerance, boolean excludeEdges ) { int edgeMode = (excludeEdges) ? 1 : 0; return findMinima(xx, tolerance, edgeMode); }
public static int[] findMinima(double[] xx, double tolerance, int edgeMode) { int len = xx.length; double[] negArr = new double[len]; for (int jj = 0; jj < len; jj++) negArr[jj] = -xx[jj]; int[] minPositions = findMaxima(negArr, tolerance, edgeMode); return minPositions; }
public static int[] findMaxima(double[] xx, double tolerance, boolean excludeOnEdges) { int edgeBehavior = (excludeOnEdges) ? 1 : 0; return findMaxima(xx, tolerance, edgeBehavior); }
/** Find the maxima of an image. * @param ip The input image * @param tolerance Height tolerance: maxima are accepted only if protruding more than this value * from the ridge to a higher maximum * @param outputType What to mark in output image: SINGLE_POINTS, IN_TOLERANCE or SEGMENTED. * No output image is created for output types POINT_SELECTION, LIST and COUNT. * @param excludeOnEdges Whether to exclude edge maxima * @return A new byteProcessor with a normal (uninverted) LUT where the marked points * are set to 255 (Background 0). Pixels outside of the roi of the input ip are not set. * Returns null if outputType does not require an output or if cancelled by escape */ public ByteProcessor findMaxima(ImageProcessor ip, double tolerance, int outputType, boolean excludeOnEdges) { return findMaxima(ip, tolerance, ImageProcessor.NO_THRESHOLD, outputType, excludeOnEdges, false); }
/** Find the maxima of an image. * @param ip The input image * @param tolerance Height tolerance: maxima are accepted only if protruding more than this value * from the ridge to a higher maximum * @param outputType What to mark in output image: SINGLE_POINTS, IN_TOLERANCE or SEGMENTED. * No output image is created for output types POINT_SELECTION, LIST and COUNT. * @param excludeOnEdges Whether to exclude edge maxima * @return A new byteProcessor with a normal (uninverted) LUT where the marked points * are set to 255 (Background 0). Pixels outside of the roi of the input ip are not set. * Returns null if outputType does not require an output or if cancelled by escape */ public ByteProcessor findMaxima(ImageProcessor ip, double tolerance, int outputType, boolean excludeOnEdges) { return findMaxima(ip, tolerance, ImageProcessor.NO_THRESHOLD, outputType, excludeOnEdges, false); }
/** Finds the image maxima and returns them as a Polygon. There * is an example at http://imagej.nih.gov/ij/macros/js/FindMaxima.js. * @param ip The input image * @param tolerance Height tolerance: maxima are accepted only if protruding more than this value * from the ridge to a higher maximum * @param excludeOnEdges Whether to exclude edge maxima * @return A Polygon containing the coordinates of the maxima */ public Polygon getMaxima(ImageProcessor ip, double tolerance, boolean excludeOnEdges) { findMaxima(ip, tolerance, ImageProcessor.NO_THRESHOLD, MaximumFinder.POINT_SELECTION, excludeOnEdges, false); if (points==null) return new Polygon(); else return points; }