/** Generate output image whose type is same as input image. */ private ImagePlus makeOutputImage(ImagePlus imp, FloatProcessor fp, int ptype) { int width = imp.getWidth(); int height = imp.getHeight(); float[] pixels = (float[]) fp.getPixels(); ImageProcessor oip = null; // Create output image consistent w/ type of input image. int size = pixels.length; switch (ptype) { case BYTE_TYPE: oip = imp.getProcessor().createProcessor(width, height); byte[] pixels8 = (byte[]) oip.getPixels(); for (int i = 0; i < size; i++) pixels8[i] = (byte) pixels[i]; break; case SHORT_TYPE: oip = imp.getProcessor().createProcessor(width, height); short[] pixels16 = (short[]) oip.getPixels(); for (int i = 0; i < size; i++) pixels16[i] = (short) pixels[i]; break; case FLOAT_TYPE: oip = new FloatProcessor(width, height, pixels, null); break; } // Adjust for display. // Calling this on non-ByteProcessors ensures image // processor is set up to correctly display image. oip.resetMinAndMax(); // Create new image plus object. Don't use // ImagePlus.createImagePlus here because there may be // attributes of input image that are not appropriate for // projection. return new ImagePlus(makeTitle(), oip); }
/** Constructs a Wand object from an ImageProcessor. */ public Wand(ImageProcessor ip) { this.ip = ip; if (ip instanceof ByteProcessor) bpixels = (byte[]) ip.getPixels(); else if (ip instanceof ColorProcessor) cpixels = (int[]) ip.getPixels(); else if (ip instanceof ShortProcessor) spixels = (short[]) ip.getPixels(); else if (ip instanceof FloatProcessor) fpixels = (float[]) ip.getPixels(); width = ip.getWidth(); height = ip.getHeight(); }
void reset(ImagePlus imp, ImageProcessor ip) { // Assign the pixels of ip to the data in the restore array, while // taking care to not give the address the restore array to the // image processor. int[] pixels = (int[]) ip.getPixels(); for (int i = 0; i < numPixels; i++) pixels[i] = restore[i]; }
/*------------------------------------------------------------------*/ void putRow(ImageProcessor ip, int y, double[] row) { int rowLength = ip.getWidth(); if (rowLength != row.length) { throw new IndexOutOfBoundsException("Incoherent array sizes"); } y *= rowLength; if (ip.getPixels() instanceof float[]) { float[] floatPixels = (float[]) ip.getPixels(); for (int i = 0; (i < rowLength); i++) { floatPixels[y++] = (float) row[i]; } } else { throw new IllegalArgumentException("Float image required"); } } /* end putRow */
/*------------------------------------------------------------------*/ void putColumn(ImageProcessor ip, int x, double[] column) { int width = ip.getWidth(); if (ip.getHeight() != column.length) { throw new IndexOutOfBoundsException("Incoherent array sizes"); } if (ip.getPixels() instanceof float[]) { float[] floatPixels = (float[]) ip.getPixels(); for (int i = 0; (i < column.length); i++) { floatPixels[x] = (float) column[i]; x += width; } } else { throw new IllegalArgumentException("Float image required"); } } /* end putColumn */
/*------------------------------------------------------------------*/ public void getHorizontalGradient(ImageProcessor ip, double tolerance) { if (!(ip.getPixels() instanceof float[])) { throw new IllegalArgumentException("Float image required"); } float[] floatPixels = (float[]) ip.getPixels(); int width = ip.getWidth(); int height = ip.getHeight(); double line[] = new double[width]; for (int y = 0; (y < height); y++) { getRow(ip, y, line); getSplineInterpolationCoefficients(line, tolerance); getGradient(line); putRow(ip, y, line); stepProgressBar(); } } /* end getHorizontalGradient */
/*------------------------------------------------------------------*/ public void getVerticalHessian(ImageProcessor ip, double tolerance) { if (!(ip.getPixels() instanceof float[])) { throw new IllegalArgumentException("Float image required"); } float[] floatPixels = (float[]) ip.getPixels(); int width = ip.getWidth(); int height = ip.getHeight(); double line[] = new double[height]; for (int x = 0; (x < width); x++) { getColumn(ip, x, line); getSplineInterpolationCoefficients(line, tolerance); getHessian(line); putColumn(ip, x, line); stepProgressBar(); } } /* end getVerticalHessian */
/** Adds the image in 'ip' to the end of the stack. */ public void addSlice(String sliceLabel, ImageProcessor ip) { if (ip.getWidth() != width || ip.getHeight() != height) throw new IllegalArgumentException("Dimensions do not match"); if (nSlices == 0) { cm = ip.getColorModel(); min = ip.getMin(); max = ip.getMax(); } addSlice(sliceLabel, ip.getPixels()); }
// Binary fill by Gabriel Landini, G.Landini at bham.ac.uk // 21/May/2008 void fill(ImageProcessor ip, int foreground, int background) { int width = ip.getWidth(); int height = ip.getHeight(); FloodFiller ff = new FloodFiller(ip); ip.setColor(127); for (int y = 0; y < height; y++) { if (ip.getPixel(0, y) == background) ff.fill(0, y); if (ip.getPixel(width - 1, y) == background) ff.fill(width - 1, y); } for (int x = 0; x < width; x++) { if (ip.getPixel(x, 0) == background) ff.fill(x, 0); if (ip.getPixel(x, height - 1) == background) ff.fill(x, height - 1); } byte[] pixels = (byte[]) ip.getPixels(); int n = width * height; for (int i = 0; i < n; i++) { if (pixels[i] == 127) pixels[i] = (byte) background; else pixels[i] = (byte) foreground; } }
public ImageProcessor getMask() { if (cachedMask != null && cachedMask.getPixels() != null) return cachedMask; ImageProcessor mask = new ByteProcessor(width, height); double a = width / 2.0, b = height / 2.0; double a2 = a * a, b2 = b * b; a -= 0.5; b -= 0.5; double xx, yy; int offset; byte[] pixels = (byte[]) mask.getPixels(); for (int y = 0; y < height; y++) { offset = y * width; for (int x = 0; x < width; x++) { xx = x - a; yy = y - b; if ((xx * xx / a2 + yy * yy / b2) <= 1.0) pixels[offset + x] = -1; } } cachedMask = mask; return mask; }
/** * Performs particle analysis on the specified ImagePlus and ImageProcessor. Returns false if * there is an error. */ public boolean analyze(ImagePlus imp, ImageProcessor ip) { if (this.imp == null) this.imp = imp; showResults = (options & SHOW_RESULTS) != 0; excludeEdgeParticles = (options & EXCLUDE_EDGE_PARTICLES) != 0; resetCounter = (options & CLEAR_WORKSHEET) != 0; showProgress = (options & SHOW_PROGRESS) != 0; floodFill = (options & INCLUDE_HOLES) == 0; recordStarts = (options & RECORD_STARTS) != 0; addToManager = (options & ADD_TO_MANAGER) != 0; displaySummary = (options & DISPLAY_SUMMARY) != 0; inSituShow = (options & IN_SITU_SHOW) != 0; outputImage = null; ip.snapshot(); ip.setProgressBar(null); if (Analyzer.isRedirectImage()) { redirectImp = Analyzer.getRedirectImage(imp); if (redirectImp == null) return false; int depth = redirectImp.getStackSize(); if (depth > 1 && depth == imp.getStackSize()) { ImageStack redirectStack = redirectImp.getStack(); redirectIP = redirectStack.getProcessor(imp.getCurrentSlice()); } else redirectIP = redirectImp.getProcessor(); } else if (imp.getType() == ImagePlus.COLOR_RGB) { ImagePlus original = (ImagePlus) imp.getProperty("OriginalImage"); if (original != null && original.getWidth() == imp.getWidth() && original.getHeight() == imp.getHeight()) { redirectImp = original; redirectIP = original.getProcessor(); } } if (!setThresholdLevels(imp, ip)) return false; width = ip.getWidth(); height = ip.getHeight(); if (!(showChoice == NOTHING || showChoice == OVERLAY_OUTLINES || showChoice == OVERLAY_MASKS)) { blackBackground = Prefs.blackBackground && inSituShow; if (slice == 1) outlines = new ImageStack(width, height); if (showChoice == ROI_MASKS) drawIP = new ShortProcessor(width, height); else drawIP = new ByteProcessor(width, height); drawIP.setLineWidth(lineWidth); if (showChoice == ROI_MASKS) { } // Place holder for now... else if (showChoice == MASKS && !blackBackground) drawIP.invertLut(); else if (showChoice == OUTLINES) { if (!inSituShow) { if (customLut == null) makeCustomLut(); drawIP.setColorModel(customLut); } drawIP.setFont(new Font("SansSerif", Font.PLAIN, fontSize)); if (fontSize > 12 && inSituShow) drawIP.setAntialiasedText(true); } outlines.addSlice(null, drawIP); if (showChoice == ROI_MASKS || blackBackground) { drawIP.setColor(Color.black); drawIP.fill(); drawIP.setColor(Color.white); } else { drawIP.setColor(Color.white); drawIP.fill(); drawIP.setColor(Color.black); } } calibration = redirectImp != null ? redirectImp.getCalibration() : imp.getCalibration(); if (rt == null) { rt = Analyzer.getResultsTable(); analyzer = new Analyzer(imp); } else analyzer = new Analyzer(imp, measurements, rt); if (resetCounter && slice == 1) { if (!Analyzer.resetCounter()) return false; } beginningCount = Analyzer.getCounter(); byte[] pixels = null; if (ip instanceof ByteProcessor) pixels = (byte[]) ip.getPixels(); if (r == null) { r = ip.getRoi(); mask = ip.getMask(); if (displaySummary) { if (mask != null) totalArea = ImageStatistics.getStatistics(ip, AREA, calibration).area; else totalArea = r.width * calibration.pixelWidth * r.height * calibration.pixelHeight; } } minX = r.x; maxX = r.x + r.width; minY = r.y; maxY = r.y + r.height; if (r.width < width || r.height < height || mask != null) { if (!eraseOutsideRoi(ip, r, mask)) return false; } int offset; double value; int inc = Math.max(r.height / 25, 1); int mi = 0; ImageWindow win = imp.getWindow(); if (win != null) win.running = true; if (measurements == 0) measurements = Analyzer.getMeasurements(); if (showChoice == ELLIPSES) measurements |= ELLIPSE; measurements &= ~LIMIT; // ignore "Limit to Threshold" roiNeedsImage = (measurements & PERIMETER) != 0 || (measurements & SHAPE_DESCRIPTORS) != 0 || (measurements & FERET) != 0; particleCount = 0; wand = new Wand(ip); pf = new PolygonFiller(); if (floodFill) { ImageProcessor ipf = ip.duplicate(); ipf.setValue(fillColor); ff = new FloodFiller(ipf); } roiType = Wand.allPoints() ? Roi.FREEROI : Roi.TRACED_ROI; for (int y = r.y; y < (r.y + r.height); y++) { offset = y * width; for (int x = r.x; x < (r.x + r.width); x++) { if (pixels != null) value = pixels[offset + x] & 255; else if (imageType == SHORT) value = ip.getPixel(x, y); else value = ip.getPixelValue(x, y); if (value >= level1 && value <= level2) analyzeParticle(x, y, imp, ip); } if (showProgress && ((y % inc) == 0)) IJ.showProgress((double) (y - r.y) / r.height); if (win != null) canceled = !win.running; if (canceled) { Macro.abort(); break; } } if (showProgress) IJ.showProgress(1.0); if (showResults) rt.updateResults(); imp.killRoi(); ip.resetRoi(); ip.reset(); if (displaySummary && IJ.getInstance() != null) updateSliceSummary(); if (addToManager && roiManager != null) roiManager.setEditMode(imp, true); maxParticleCount = (particleCount > maxParticleCount) ? particleCount : maxParticleCount; totalCount += particleCount; if (!canceled) showResults(); return true; }
ImageProcessor setup(ImagePlus imp) { ImageProcessor ip; int type = imp.getType(); if (type != ImagePlus.COLOR_RGB) return null; ip = imp.getProcessor(); int id = imp.getID(); int slice = imp.getCurrentSlice(); if ((id != previousImageID) | (slice != previousSlice) | (flag)) { flag = false; // if true, flags a change from HSB to RGB or viceversa numSlices = imp.getStackSize(); stack = imp.getStack(); width = stack.getWidth(); height = stack.getHeight(); numPixels = width * height; hSource = new byte[numPixels]; sSource = new byte[numPixels]; bSource = new byte[numPixels]; // restore = (int[])ip.getPixelsCopy(); //This runs into trouble sometimes, so do it the // long way: int[] temp = (int[]) ip.getPixels(); restore = new int[numPixels]; for (int i = 0; i < numPixels; i++) restore[i] = temp[i]; fillMask = new int[numPixels]; // Get hsb or rgb from image. ColorProcessor cp = (ColorProcessor) ip; IJ.showStatus("Gathering data"); if (isRGB) cp.getRGB(hSource, sSource, bSource); else cp.getHSB(hSource, sSource, bSource); IJ.showStatus("done"); // Create a spectrum ColorModel for the Hue histogram plot. Color c; byte[] reds = new byte[256]; byte[] greens = new byte[256]; byte[] blues = new byte[256]; for (int i = 0; i < 256; i++) { c = Color.getHSBColor(i / 255f, 1f, 1f); reds[i] = (byte) c.getRed(); greens[i] = (byte) c.getGreen(); blues[i] = (byte) c.getBlue(); } ColorModel cm = new IndexColorModel(8, 256, reds, greens, blues); // Make an image with just the hue from the RGB image and the spectrum LUT. // This is just for a hue histogram for the plot. Do not show it. // ByteProcessor bpHue = new ByteProcessor(width,height,h,cm); ByteProcessor bpHue = new ByteProcessor(width, height, hSource, cm); ImagePlus impHue = new ImagePlus("Hue", bpHue); // impHue.show(); ByteProcessor bpSat = new ByteProcessor(width, height, sSource, cm); ImagePlus impSat = new ImagePlus("Sat", bpSat); // impSat.show(); ByteProcessor bpBri = new ByteProcessor(width, height, bSource, cm); ImagePlus impBri = new ImagePlus("Bri", bpBri); // impBri.show(); plot.setHistogram(impHue, 0); splot.setHistogram(impSat, 1); bplot.setHistogram(impBri, 2); updateLabels(); updatePlot(); updateScrollBars(); imp.updateAndDraw(); } previousImageID = id; previousSlice = slice; return ip; }
/*------------------------------------------------------------------*/ void doIt(ImageProcessor ip) { int width = ip.getWidth(); int height = ip.getHeight(); double hLine[] = new double[width]; double vLine[] = new double[height]; if (!(ip.getPixels() instanceof float[])) { throw new IllegalArgumentException("Float image required"); } switch (operation) { case GRADIENT_MAGNITUDE: { ImageProcessor h = ip.duplicate(); ImageProcessor v = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsH = (float[]) h.getPixels(); float[] floatPixelsV = (float[]) v.getPixels(); getHorizontalGradient(h, FLT_EPSILON); getVerticalGradient(v, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) Math.sqrt( floatPixelsH[k] * floatPixelsH[k] + floatPixelsV[k] * floatPixelsV[k]); } stepProgressBar(); } } break; case GRADIENT_DIRECTION: { ImageProcessor h = ip.duplicate(); ImageProcessor v = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsH = (float[]) h.getPixels(); float[] floatPixelsV = (float[]) v.getPixels(); getHorizontalGradient(h, FLT_EPSILON); getVerticalGradient(v, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) Math.atan2(floatPixelsH[k], floatPixelsV[k]); } stepProgressBar(); } } break; case LAPLACIAN: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) (floatPixelsHH[k] + floatPixelsVV[k]); } stepProgressBar(); } } break; case LARGEST_HESSIAN: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); ImageProcessor hv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); float[] floatPixelsHV = (float[]) hv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); getCrossHessian(hv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) (0.5 * (floatPixelsHH[k] + floatPixelsVV[k] + Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } stepProgressBar(); } } break; case SMALLEST_HESSIAN: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); ImageProcessor hv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); float[] floatPixelsHV = (float[]) hv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); getCrossHessian(hv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) (0.5 * (floatPixelsHH[k] + floatPixelsVV[k] - Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } stepProgressBar(); } } break; case HESSIAN_ORIENTATION: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); ImageProcessor hv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); float[] floatPixelsHV = (float[]) hv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); getCrossHessian(hv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { if (floatPixelsHV[k] < 0.0) { floatPixels[k] = (float) (-0.5 * Math.acos( (floatPixelsHH[k] - floatPixelsVV[k]) / Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } else { floatPixels[k] = (float) (0.5 * Math.acos( (floatPixelsHH[k] - floatPixelsVV[k]) / Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } } stepProgressBar(); } } break; default: throw new IllegalArgumentException("Invalid operation"); } ip.resetMinAndMax(); imp.updateAndDraw(); } /* end doIt */