Search in sources :

Example 1 with FloatBlitter

use of ij.process.FloatBlitter in project gdsc by aherbert.

the class CellOutliner_PlugIn method findCells.

@Nullable
private PolygonRoi[] findCells(ImageProcessor inputProcessor) {
    // Limit processing to where it is needed
    final Rectangle bounds = createBounds(inputProcessor, xpoints, ypoints, getCellRange());
    ImageProcessor ip = inputProcessor.duplicate();
    ip.setRoi(bounds);
    ip = ip.crop();
    if (kernels == null) {
        kernels = createKernels();
        convolved = null;
    }
    if (convolved == null) {
        convolved = convolveImage(ip, kernels);
    // showConvolvedImages(convolved)
    }
    if (ImageJUtils.isInterrupted()) {
        return null;
    }
    FloatProcessor combinedIp = null;
    Blitter blitter = null;
    ImagePlus combinedImp = null;
    if (debug) {
        combinedIp = new FloatProcessor(ip.getWidth(), ip.getHeight());
        blitter = new FloatBlitter(combinedIp);
        combinedImp = displayImage(combinedIp, "Combined edge projection");
    }
    final PolygonRoi[] cells = new PolygonRoi[xpoints.length];
    if (!this.buildMaskOutput) {
        IJ.showStatus("Finding cells ...");
    }
    // Process each point
    for (int n = 0; n < xpoints.length; n++) {
        if (!this.buildMaskOutput) {
            IJ.showProgress(n, xpoints.length);
        }
        final int cx = xpoints[n] - bounds.x;
        final int cy = ypoints[n] - bounds.y;
        // Restrict bounds using the cell radius and tolerance
        final Rectangle pointBounds = createBounds(ip, cx, cy, cx, cy, getCellRange());
        // Calculate the angle
        final FloatProcessor angle = createAngleProcessor(cx, cy, pointBounds);
        if (ImageJUtils.isInterrupted()) {
            return null;
        }
        final FloatProcessor edgeProjection = computeEdgeProjection(convolved, pointBounds, angle);
        // Initialise the edge as a circle.
        PolygonRoi cell = null;
        double[] params = { cx - pointBounds.x, cy - pointBounds.y, settings.cellRadius, settings.cellRadius, settings.cellRadius, 0 };
        final double range = settings.cellRadius * 0.9;
        // Iterate to find the best cell outline
        boolean returnEllipticalFit = settings.ellipticalFit;
        for (int iter = 0; iter < settings.iterations; iter++) {
            // Use the current elliptical edge to define the weights for the edge projection
            final FloatProcessor weights = createWeightMap(pointBounds, params, range);
            if (ImageJUtils.isInterrupted() || weights == null) {
                return null;
            }
            if (debug) {
                displayImage(weights, "Weight map");
            }
            final FloatProcessor weightedEdgeProjection = applyWeights(edgeProjection, weights);
            if (debug) {
                blitter.copyBits(weightedEdgeProjection, pointBounds.x, pointBounds.y, Blitter.ADD);
                combinedIp.resetMinAndMax();
                combinedImp.updateAndDraw();
                displayImage(weightedEdgeProjection, "Weighted edge projection");
            }
            cell = findPolygonalCell((int) Math.round(params[0]), (int) Math.round(params[1]), weightedEdgeProjection, angle);
            // weights
            final FloatProcessor weightMap = weightedEdgeProjection;
            final double[] newParams = fitPolygonalCell(cell, params, weightMap);
            if (newParams == null) {
                returnEllipticalFit = false;
                break;
            }
            // Set the parameters for the weight map
            params = newParams;
        }
        assert cell != null : "No cell";
        // Return either the fitted elliptical cell or the last polygon outline
        if (returnEllipticalFit) {
            final EllipticalCell e = new EllipticalCell();
            final FloatPolygon ellipse = e.drawEllipse(params);
            cell = new PolygonRoi(ellipse.xpoints, ellipse.ypoints, ellipse.npoints, Roi.POLYGON);
        }
        PolygonRoi finalCell = cell;
        if (settings.dilate > 0) {
            // Dilate the cell and then trace the new outline
            final ByteProcessor bp = new ByteProcessor(pointBounds.width, pointBounds.height);
            bp.setColor(CELL & 0xff);
            bp.draw(cell);
            for (int i = 0; i < settings.dilate; i++) {
                dilate(bp);
            }
            cell = traceOutline(bp);
            if (cell != null) {
                finalCell = cell;
            }
        }
        final Rectangle pos = finalCell.getBounds();
        // Does not work in IJ 1.46+
        // finalCell.setLocation(pos.x + bounds.x + pointBounds.x, pos.y + bounds.y + pointBounds.y)
        // Create a new Polygon with the correct coordinates. This is required since IJ 1.46
        // since setting the location is not passed through when drawing an overlay
        final int[] xCoords = finalCell.getXCoordinates();
        final int[] yCoords = finalCell.getYCoordinates();
        final int npoints = finalCell.getNCoordinates();
        for (int i = 0; i < npoints; i++) {
            xCoords[i] += pos.x + bounds.x + pointBounds.x;
            yCoords[i] += pos.y + bounds.y + pointBounds.y;
        }
        finalCell = new PolygonRoi(xCoords, yCoords, npoints, Roi.POLYGON);
        cells[n] = finalCell;
    }
    return cells;
}
Also used : ByteProcessor(ij.process.ByteProcessor) FloatProcessor(ij.process.FloatProcessor) Rectangle(java.awt.Rectangle) Blitter(ij.process.Blitter) FloatBlitter(ij.process.FloatBlitter) ImagePlus(ij.ImagePlus) Point(java.awt.Point) ImageProcessor(ij.process.ImageProcessor) FloatBlitter(ij.process.FloatBlitter) PolygonRoi(ij.gui.PolygonRoi) FloatPolygon(ij.process.FloatPolygon) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Aggregations

ImagePlus (ij.ImagePlus)1 PolygonRoi (ij.gui.PolygonRoi)1 Blitter (ij.process.Blitter)1 ByteProcessor (ij.process.ByteProcessor)1 FloatBlitter (ij.process.FloatBlitter)1 FloatPolygon (ij.process.FloatPolygon)1 FloatProcessor (ij.process.FloatProcessor)1 ImageProcessor (ij.process.ImageProcessor)1 Point (java.awt.Point)1 Rectangle (java.awt.Rectangle)1 Nullable (uk.ac.sussex.gdsc.core.annotation.Nullable)1