import ij.IJ; import ij.ImagePlus; import ij.gui.GenericDialog; import ij.gui.Line; import ij.gui.Overlay; import ij.gui.PolygonRoi; import ij.gui.ProfilePlot; import ij.process.FloatProcessor; import ij.process.ImageProcessor; import java.awt.Color; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; private double midLineWidth = 15.0; private double normRegionWidth = 20.0; float[][] calcWeightedCoords(ImageProcessor ip) { int width = ip.getWidth(); int height = ip.getHeight(); float[][] output = new float[2][width]; for (int x = 0; x < width; x++) { float sumWeights = 0.0f; float weightedSum = 0.0f; for (int y = 0; y < height; y++) { float p = ip.getPixelValue(x, y); weightedSum += y * p; sumWeights += p; } output[0][x] = x; output[1][x] = weightedSum / sumWeights; } return output; } boolean showDialog() { GenericDialog gd = new GenericDialog("Projection Analyser"); gd.addNumericField("Specify midline extent", midLineWidth, 0, 3, "%"); gd.addNumericField("Specify normalisation region extent", normRegionWidth, 0, 3, "%"); gd.showDialog(); if (!gd.wasOKed()) { return false; } midLineWidth = gd.getNextNumber(); normRegionWidth = gd.getNextNumber(); return true; } ImagePlus normImage(ImageProcessor ip, double[] profileData) { FloatProcessor fp = ip.convertToFloatProcessor(); ImagePlus output = new ImagePlus("Normalised " + imp.getShortTitle(), fp); DescriptiveStatistics stats = new DescriptiveStatistics(); int extent = (int) Math.round(normRegionWidth * ip.getWidth() / 100.0); for (int i = 0; i < extent; i++) { stats.addValue(profileData[i]); } fp.multiply(1.0 / stats.getMean()); fp.resetMinAndMax(); output.resetDisplayRange(); return output; } ImagePlus imp = IJ.getImage(); if (!showDialog()) { return; } float[][] weightedMidLine = calcWeightedCoords(imp.getProcessor()); PolygonRoi roi = new PolygonRoi(weightedMidLine[0], weightedMidLine[1], weightedMidLine[0].length, PolygonRoi.POLYLINE); roi.fitSpline(); roi.setStrokeWidth(imp.getHeight() * midLineWidth / 100.0); imp.setRoi(roi); ProfilePlot pp1 = new ProfilePlot(imp); ImagePlus norm = normImage(imp.getProcessor().duplicate(), pp1.getProfile()); imp.deleteRoi(); norm.setRoi(roi); ProfilePlot pp2 = new ProfilePlot(norm); pp2.createWindow(); Overlay o = new Overlay(); int width = imp.getWidth(); int height = imp.getHeight(); double xr = width * normRegionWidth / 100.0; o.add(new Line(xr, 0.0, xr, height - 1.0)); o.setStrokeColor(Color.red); norm.setOverlay(o); norm.show();