All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.mianalysis.mia.module.visualise.overlays.AddLabels Maven / Gradle / Ivy

Go to download

ModularImageAnalysis (MIA) is an ImageJ plugin which provides a modular framework for assembling image and object analysis workflows. Detected objects can be transformed, filtered, measured and related. Analysis workflows are batch-enabled by default, allowing easy processing of high-content datasets.

There is a newer version: 1.6.12
Show newest version
package io.github.mianalysis.mia.module.visualise.overlays;

import java.awt.Color;
import java.awt.Font;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.scijava.Priority;
import org.scijava.plugin.Plugin;

import com.drew.lang.annotations.Nullable;

import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.gui.TextRoi;
import ij.plugin.Duplicator;
import ij.plugin.HyperStackConverter;
import io.github.mianalysis.mia.module.Categories;
import io.github.mianalysis.mia.module.Category;
import io.github.mianalysis.mia.module.Module;
import io.github.mianalysis.mia.module.Modules;
import io.github.mianalysis.mia.module.images.process.FilterImage;
import io.github.mianalysis.mia.module.images.process.binary.BinaryOperations2D;
import io.github.mianalysis.mia.module.images.process.binary.DistanceMap;
import io.github.mianalysis.mia.object.Obj;
import io.github.mianalysis.mia.object.Objs;
import io.github.mianalysis.mia.object.Workspace;
import io.github.mianalysis.mia.object.coordinates.Point;
import io.github.mianalysis.mia.object.image.Image;
import io.github.mianalysis.mia.object.image.ImageFactory;
import io.github.mianalysis.mia.object.parameters.BooleanP;
import io.github.mianalysis.mia.object.parameters.ChildObjectsP;
import io.github.mianalysis.mia.object.parameters.ChoiceP;
import io.github.mianalysis.mia.object.parameters.InputImageP;
import io.github.mianalysis.mia.object.parameters.InputObjectsP;
import io.github.mianalysis.mia.object.parameters.ObjectMeasurementP;
import io.github.mianalysis.mia.object.parameters.ObjectMetadataP;
import io.github.mianalysis.mia.object.parameters.OutputImageP;
import io.github.mianalysis.mia.object.parameters.Parameters;
import io.github.mianalysis.mia.object.parameters.ParentObjectsP;
import io.github.mianalysis.mia.object.parameters.PartnerObjectsP;
import io.github.mianalysis.mia.object.parameters.SeparatorP;
import io.github.mianalysis.mia.object.parameters.text.IntegerP;
import io.github.mianalysis.mia.object.parameters.text.StringP;
import io.github.mianalysis.mia.object.refs.collections.ImageMeasurementRefs;
import io.github.mianalysis.mia.object.refs.collections.MetadataRefs;
import io.github.mianalysis.mia.object.refs.collections.ObjMeasurementRefs;
import io.github.mianalysis.mia.object.refs.collections.ObjMetadataRefs;
import io.github.mianalysis.mia.object.refs.collections.ParentChildRefs;
import io.github.mianalysis.mia.object.refs.collections.PartnerRefs;
import io.github.mianalysis.mia.object.system.Status;
import io.github.mianalysis.mia.process.LabelFactory;

/**
 * Adds an overlay to the specified input image with each object represented by
 * a text label. The label can include information such as measurements,
 * associated object counts or ID numbers.
 */
@Plugin(type = Module.class, priority = Priority.LOW, visible = true)
public class AddLabels extends AbstractOverlay {
    TextRoi textRoi = null;

    /**
    * 
    */
    public static final String INPUT_SEPARATOR = "Image and object input";

    /**
     * Image onto which overlay will be rendered. Input image will only be updated
     * if "Apply to input image" is enabled, otherwise the image containing the
     * overlay will be stored as a new image with name specified by "Output image".
     */
    public static final String INPUT_IMAGE = "Input image";

    /**
     * Objects to represent as overlays.
     */
    public static final String INPUT_OBJECTS = "Input objects";

    /**
    * 
    */
    public static final String OUTPUT_SEPARATOR = "Image output";

    /**
     * Determines if the modifications made to the input image (added overlay
     * elements) will be applied to that image or directed to a new image. When
     * selected, the input image will be updated.
     */
    public static final String APPLY_TO_INPUT = "Apply to input image";

    /**
     * If the modifications (overlay) aren't being applied directly to the input
     * image, this control will determine if a separate image containing the overlay
     * should be saved to the workspace.
     */
    public static final String ADD_OUTPUT_TO_WORKSPACE = "Add output image to workspace";

    /**
     * The name of the new image to be saved to the workspace (if not applying the
     * changes directly to the input image).
     */
    public static final String OUTPUT_IMAGE = "Output image";

    /**
    * 
    */
    public static final String CONTENT_SEPARATOR = "Overlay content";

    /**
     * Controls what information each label displays:
*
    *
  • "Child count" The number of children from a specific object collection * for each object. The children to summarise are selected using the "Child * objects for label" parameter.
  • *
  • "ID" The ID number of the object.
  • *
  • "Measurement value" A measurement associated with the object. The * measurement is selected using the "Measurement for label" parameter.
  • *
  • "Parent ID" The ID number of a parent of the object. The parent object is * selected using the "Parent object for label" parameter.
  • *
  • "Parent measurement value" A measurement associated with a parent of the * object. The measurement is selected using the "Measurement for label" * parameter and the parent object with the "Parent object for label" * parameter.
  • *
  • "Partner count" The number of partners from a specific object collection * for each object. The partners to summarise are selected using the "Partner * objects for label" parameter.
  • *
*/ public static final String LABEL_MODE = "Label mode"; /** * Number of decimal places to use when displaying numeric values. */ public static final String DECIMAL_PLACES = "Decimal places"; /** * When enabled, numeric values will be displayed in the format 1.23E-3. * Otherwise, the same value would appear as 0.00123. */ public static final String USE_SCIENTIFIC = "Use scientific notation"; /** * Font size of the text label. */ public static final String LABEL_SIZE = "Label size"; /** * Offset the label by this number of pixels horizontally (along the x-axis). * Increasingly positive numbers move the label right. */ public static final String X_OFFSET = "X-offset"; /** * Offset the label by this number of pixels vertically (along the y-axis). * Increasingly positive numbers move the label down. */ public static final String Y_OFFSET = "Y-offset"; /** * */ public static final String CENTRE_TEXT = "Centre text"; /** * If "Label mode" is set to "Child count", these are the child objects which * will be counted and displayed on the label. These objects will be children of * the input objects. */ public static final String CHILD_OBJECTS_FOR_LABEL = "Child objects for label"; /** * If "Label mode" is set to either "Parent ID" or "Parent measurement value", * these are the parent objects which will be used. These objects will be * parents of the input objects. */ public static final String PARENT_OBJECT_FOR_LABEL = "Parent object for label"; /** * If "Label mode" is set to "Partner count", these are the partner objects * which will be counted and displayed on the label. These objects will be * partners of the input objects. */ public static final String PARTNER_OBJECTS_FOR_LABEL = "Partner objects for label"; /** * If "Label mode" is set to either "Measurement value" or "Parent measurement * value", these are the measurements which will be used. */ public static final String MEASUREMENT_FOR_LABEL = "Measurement for label"; public static final String OBJECT_METADATA_FOR_LABEL = "Metadata item for label"; /** * Text to display at beginning of every label */ public static final String PREFIX = "Prefix"; /** * Text to display at end of every label */ public static final String SUFFIX = "Suffix"; /** * */ public static final String LOCATION_SEPARATOR = "Overlay location"; /** * Determines the method used for placing the label overlay for each object:
*
    *
  • "Centre of object" Labels will be placed at the centroid (average * coordinate location) of each object. This position won't necessarily coincide * with a region corresponding to that object. For example, the centroid of a * crescent shape won't lie on the crescent itself.
  • *
  • "Fixed value" Labels will be placed at the x,y,z location specified by * the user.
  • *
  • "Inside largest part of object" Labels will be placed coincident with the * largest region of each object. This ensures the label is placed directly over * the relevant object.
  • *
  • "Object measurement" Labels will be placed coincident with the specified * measurements for each object.
  • *
*/ public static final String LABEL_POSITION = "Label position"; /** * Object measurement specifying the X-position of the label. Measurement value * must be specified in pixel units. */ public static final String X_POSITION_MEASUREMENT = "X-position measurement"; /** * Object measurement specifying the Y-position of the label. Measurement value * must be specified in pixel units. */ public static final String Y_POSITION_MEASUREMENT = "Y-position measurement"; /** * Object measurement specifying the Z-position (slice) of the label. * Measurement value must be specified in slice units. */ public static final String Z_POSITION_MEASUREMENT = "Z-position measurement"; /** * Fixed value specifying the X-position of the label. Specified in pixel units. */ public static final String X_POSITION = "X-position"; /** * Fixed value specifying the Y-position of the label. Specified in pixel units. */ public static final String Y_POSITION = "Y-position"; /** * Fixed value specifying the Z-position of the label. Specified in pixel units. */ public static final String Z_POSITION = "Z-position"; /** * Display overlay elements in all slices corresponding to that object. */ public static final String RENDER_IN_ALL_OBJECT_SLICES = "Render in all object slices"; /** * Display overlay elements in all frames, irrespective of whether each object * is present in that frame. */ public static final String RENDER_IN_ALL_FRAMES = "Render in all frames"; /** * */ public static final String EXECUTION_SEPARATOR = "Execution controls"; /** * Process multiple overlay elements simultaneously. This can provide a speed * improvement when working on a computer with a multi-core CPU. */ public static final String ENABLE_MULTITHREADING = "Enable multithreading"; public AddLabels(Modules modules) { super("Add labels", modules); } public interface LabelModes extends LabelFactory.LabelModes { } public interface LabelPositions { String CENTRE = "Centre of object"; String FIXED_VALUE = "Fixed value"; String INSIDE = "Inside largest part of object"; String OBJECT_MEASUREMENT = "Object measurement"; String[] ALL = new String[] { CENTRE, FIXED_VALUE, INSIDE, OBJECT_MEASUREMENT }; } public static double[] getMeanObjectLocation(Obj object) { double xMean = object.getXMean(true); double yMean = object.getYMean(true); double zMean = object.getZMean(true, false); int z = (int) Math.round(zMean + 1); return new double[] { xMean, yMean, z }; } public static double[] getInsideObjectLocation(Obj obj) { // Binarise object and calculate its distance map Image binaryImage = obj.getAsImage("Binary", false); BinaryOperations2D.process(binaryImage, BinaryOperations2D.OperationModes.ERODE, 1, 1, true); ImagePlus distanceIpl = DistanceMap .process(binaryImage, "Distance", true, DistanceMap.WeightModes.WEIGHTS_3_4_5_7, true, false) .getImagePlus(); ImageStack distanceIst = distanceIpl.getStack(); // Get location of largest value Point bestPoint = null; double distance = Double.MIN_VALUE; for (Point point : obj.getCoordinateSet()) { int idx = distanceIpl.getStackIndex(1, point.getZ() + 1, obj.getT() + 1); float currDistance = distanceIst.getProcessor(idx).getf(point.getX(), point.getY()); if (currDistance > distance) { distance = currDistance; bestPoint = point; } } // Returning this point return new double[] { bestPoint.getX(), bestPoint.getY(), bestPoint.getZ() + 1 }; } public static double[] getMeasurementObjectLocation(Obj obj, String[] measurements) { double x; double y; double z; if (obj.getMeasurement(measurements[0]) != null) x = obj.getMeasurement(measurements[0]).getValue(); else x = 0; if (obj.getMeasurement(measurements[1]) != null) y = obj.getMeasurement(measurements[1]).getValue(); else y = 0; if (obj.getMeasurement(measurements[2]) != null) z = obj.getMeasurement(measurements[2]).getValue(); else z = 0; // Returning this point return new double[] { x, y, z }; } public static void addOverlay(ImagePlus ipl, Objs inputObjects, String labelPosition, HashMap labels, int labelSize, int xOffset, int yOffset, boolean centreText, HashMap colours, boolean renderInAllSlices, boolean renderInAllFrames, boolean multithread, @Nullable String[] measurementNames, @Nullable int[] positions) { // If necessary, turning the image into a HyperStack (if 2 dimensions=1 it will // be a standard ImagePlus) if (!ipl.isComposite() & (ipl.getNSlices() > 1 | ipl.getNFrames() > 1 | ipl.getNChannels() > 1)) ipl = HyperStackConverter.toHyperStack(ipl, ipl.getNChannels(), ipl.getNSlices(), ipl.getNFrames()); // Adding the overlay element try { int nThreads = multithread ? Prefs.getThreads() : 1; ThreadPoolExecutor pool = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); // Running through each object, adding it to the overlay along with an ID label for (Obj object : inputObjects.values()) { ImagePlus finalIpl = ipl; Runnable task = () -> { int t1 = object.getT() + 1; int t2 = object.getT() + 1; if (renderInAllFrames) { t1 = 1; t2 = finalIpl.getNFrames(); } Color colour = colours.get(object.getID()); String label = labels == null ? "" : labels.get(object.getID()); double[] location; switch (labelPosition) { case LabelPositions.CENTRE: default: location = getMeanObjectLocation(object); break; case LabelPositions.FIXED_VALUE: location = new double[] { positions[0], positions[1], positions[2] }; break; case LabelPositions.INSIDE: location = getInsideObjectLocation(object); break; case LabelPositions.OBJECT_MEASUREMENT: location = getMeasurementObjectLocation(object, measurementNames); break; } location[0] = location[0] + xOffset; location[1] = location[1] + yOffset; for (int t = t1; t <= t2; t++) { if (renderInAllSlices) { double[][] extents = object.getExtents(true, false); int zMin = (int) Math.round(extents[2][0]); int zMax = (int) Math.round(extents[2][1]); for (int z = zMin; z <= zMax; z++) { location[2] = z + 1; addOverlay(finalIpl, label, location, t, colour, labelSize, centreText); } } else { addOverlay(finalIpl, label, location, t, colour, labelSize, centreText); } } }; pool.submit(task); } pool.shutdown(); pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS); // i.e. never terminate early } catch (InterruptedException e) { // Do nothing as the user has selected this } } public static void addOverlay(ImagePlus ipl, String label, double[] labelCoords, int t, Color colour, int labelSize, boolean centreText) { if (ipl.getOverlay() == null) ipl.setOverlay(new ij.gui.Overlay()); // Adding text label TextRoi text = new TextRoi(labelCoords[0], labelCoords[1], label, new Font(Font.SANS_SERIF, Font.PLAIN, labelSize)); text.setStrokeColor(colour); text.setAntialiased(true); if (ipl.isHyperStack()) { text.setPosition(1, (int) labelCoords[2], t); } else { text.setPosition((int) Math.max(Math.max(1, labelCoords[2]), t)); } if (centreText) { text.setLocation(text.getXBase() - text.getFloatWidth() / 2 + 1, text.getYBase() - text.getFloatHeight() / 2 + 1); } ipl.getOverlay().addElement(text); } public HashMap getLabels(Objs inputObjects, String labelMode, DecimalFormat df, String childObjectsForLabelName, String parentObjectsForLabelName, String partnerObjectsForLabelName, String measurementForLabel, String objectMetadataForLabel) { switch (labelMode) { case LabelModes.CHILD_COUNT: return LabelFactory.getChildCountLabels(inputObjects, childObjectsForLabelName, df); case LabelModes.ID: return LabelFactory.getIDLabels(inputObjects, df); case LabelModes.MEASUREMENT_VALUE: return LabelFactory.getMeasurementLabels(inputObjects, measurementForLabel, df); case LabelModes.OBJECT_METADATA_ITEM: return LabelFactory.getObjectMetadataLabels(inputObjects, objectMetadataForLabel, df); case LabelModes.PARENT_ID: return LabelFactory.getParentIDLabels(inputObjects, parentObjectsForLabelName, df); case LabelModes.PARENT_MEASUREMENT_VALUE: return LabelFactory.getParentMeasurementLabels(inputObjects, parentObjectsForLabelName, measurementForLabel, df); case LabelModes.PARTNER_COUNT: return LabelFactory.getPartnerCountLabels(inputObjects, partnerObjectsForLabelName, df); } return null; } public void appendPrefixSuffix(HashMap labels, String prefix, String suffix) { if (prefix.equals("") && suffix.equals("")) return; for (int key : labels.keySet()) { String label = labels.get(key); labels.put(key, prefix + label + suffix); } } @Override public Category getCategory() { return Categories.VISUALISATION_OVERLAYS; } @Override public String getVersionNumber() { return "1.0.0"; } @Override public String getDescription() { return "Adds an overlay to the specified input image with each object represented by a text label. The label can include information such as measurements, associated object counts or ID numbers."; } @Override protected Status process(Workspace workspace) { // Getting parameters boolean applyToInput = parameters.getValue(APPLY_TO_INPUT, workspace); boolean addOutputToWorkspace = parameters.getValue(ADD_OUTPUT_TO_WORKSPACE, workspace); String outputImageName = parameters.getValue(OUTPUT_IMAGE, workspace); // Getting input objects String inputObjectsName = parameters.getValue(INPUT_OBJECTS, workspace); Objs inputObjects = workspace.getObjects().get(inputObjectsName); // Getting input image String inputImageName = parameters.getValue(INPUT_IMAGE, workspace); Image inputImage = workspace.getImages().get(inputImageName); ImagePlus ipl = inputImage.getImagePlus(); // Getting label settings String labelMode = parameters.getValue(LABEL_MODE, workspace); int labelSize = parameters.getValue(LABEL_SIZE, workspace); int xOffset = parameters.getValue(X_OFFSET, workspace); int yOffset = parameters.getValue(Y_OFFSET, workspace); boolean centreText = parameters.getValue(CENTRE_TEXT, workspace); int decimalPlaces = parameters.getValue(DECIMAL_PLACES, workspace); boolean useScientific = parameters.getValue(USE_SCIENTIFIC, workspace); String childObjectsForLabelName = parameters.getValue(CHILD_OBJECTS_FOR_LABEL, workspace); String parentObjectsForLabelName = parameters.getValue(PARENT_OBJECT_FOR_LABEL, workspace); String partnerObjectsForLabelName = parameters.getValue(PARTNER_OBJECTS_FOR_LABEL, workspace); String measurementForLabel = parameters.getValue(MEASUREMENT_FOR_LABEL, workspace); String objectMetadataForLabel = parameters.getValue(OBJECT_METADATA_FOR_LABEL, workspace); String prefix = parameters.getValue(PREFIX, workspace); String suffix = parameters.getValue(SUFFIX, workspace); String labelPosition = parameters.getValue(LABEL_POSITION, workspace); String xPosMeas = parameters.getValue(X_POSITION_MEASUREMENT, workspace); String yPosMeas = parameters.getValue(Y_POSITION_MEASUREMENT, workspace); String zPosMeas = parameters.getValue(Z_POSITION_MEASUREMENT, workspace); int xPos = parameters.getValue(X_POSITION, workspace); int yPos = parameters.getValue(Y_POSITION, workspace); int zPos = parameters.getValue(Z_POSITION, workspace); boolean renderInAllSlices = parameters.getValue(RENDER_IN_ALL_OBJECT_SLICES, workspace); boolean renderInAllFrames = parameters.getValue(RENDER_IN_ALL_FRAMES, workspace); boolean multithread = parameters.getValue(ENABLE_MULTITHREADING, workspace); String[] measurementNames = new String[] { xPosMeas, yPosMeas, zPosMeas }; int[] positions = new int[] { xPos, yPos, zPos }; // Only add output to workspace if not applying to input if (applyToInput) addOutputToWorkspace = false; // Duplicating the image, so the original isn't altered if (!applyToInput) ipl = new Duplicator().run(ipl); // Generating colours for each object HashMap colours = getColours(inputObjects, workspace); DecimalFormat df = LabelFactory.getDecimalFormat(decimalPlaces, useScientific); HashMap labels = getLabels(inputObjects, labelMode, df, childObjectsForLabelName, parentObjectsForLabelName, partnerObjectsForLabelName, measurementForLabel, objectMetadataForLabel); appendPrefixSuffix(labels, prefix, suffix); addOverlay(ipl, inputObjects, labelPosition, labels, labelSize, xOffset, yOffset, centreText, colours, renderInAllSlices, renderInAllFrames, multithread, measurementNames, positions); Image outputImage = ImageFactory.createImage(outputImageName, ipl); // If necessary, adding output image to workspace. This also allows us to show // it. if (addOutputToWorkspace) workspace.addImage(outputImage); if (showOutput) outputImage.show(); return Status.PASS; } @Override protected void initialiseParameters() { super.initialiseParameters(); parameters.add(new SeparatorP(INPUT_SEPARATOR, this)); parameters.add(new InputImageP(INPUT_IMAGE, this)); parameters.add(new InputObjectsP(INPUT_OBJECTS, this)); parameters.add(new SeparatorP(OUTPUT_SEPARATOR, this)); parameters.add(new BooleanP(APPLY_TO_INPUT, this, false)); parameters.add(new BooleanP(ADD_OUTPUT_TO_WORKSPACE, this, false)); parameters.add(new OutputImageP(OUTPUT_IMAGE, this)); parameters.add(new SeparatorP(CONTENT_SEPARATOR, this)); parameters.add(new ChoiceP(LABEL_MODE, this, LabelModes.ID, LabelModes.ALL)); parameters.add(new IntegerP(DECIMAL_PLACES, this, 0)); parameters.add(new BooleanP(USE_SCIENTIFIC, this, false)); parameters.add(new IntegerP(LABEL_SIZE, this, 8)); parameters.add(new IntegerP(X_OFFSET, this, 0)); parameters.add(new IntegerP(Y_OFFSET, this, 0)); parameters.add(new BooleanP(CENTRE_TEXT, this, true)); parameters.add(new ChildObjectsP(CHILD_OBJECTS_FOR_LABEL, this)); parameters.add(new ParentObjectsP(PARENT_OBJECT_FOR_LABEL, this)); parameters.add(new PartnerObjectsP(PARTNER_OBJECTS_FOR_LABEL, this)); parameters.add(new ObjectMeasurementP(MEASUREMENT_FOR_LABEL, this)); parameters.add(new ObjectMetadataP(OBJECT_METADATA_FOR_LABEL, this)); parameters.add(new StringP(PREFIX, this)); parameters.add(new StringP(SUFFIX, this)); parameters.add(new SeparatorP(LOCATION_SEPARATOR, this)); parameters.add(new ChoiceP(LABEL_POSITION, this, LabelPositions.CENTRE, LabelPositions.ALL)); parameters.add(new ObjectMeasurementP(X_POSITION_MEASUREMENT, this)); parameters.add(new ObjectMeasurementP(Y_POSITION_MEASUREMENT, this)); parameters.add(new ObjectMeasurementP(Z_POSITION_MEASUREMENT, this)); parameters.add(new IntegerP(X_POSITION, this, 0)); parameters.add(new IntegerP(Y_POSITION, this, 0)); parameters.add(new IntegerP(Z_POSITION, this, 0)); parameters.add(new BooleanP(RENDER_IN_ALL_OBJECT_SLICES, this, false)); parameters.add(new BooleanP(RENDER_IN_ALL_FRAMES, this, false)); parameters.add(new SeparatorP(EXECUTION_SEPARATOR, this)); parameters.add(new BooleanP(ENABLE_MULTITHREADING, this, true)); addParameterDescriptions(); } @Override public Parameters updateAndGetParameters() { Workspace workspace = null; String inputObjectsName = parameters.getValue(INPUT_OBJECTS, workspace); String parentObjectsName = parameters.getValue(PARENT_OBJECT_FOR_LABEL, workspace); Parameters returnedParameters = new Parameters(); returnedParameters.add(parameters.getParameter(INPUT_SEPARATOR)); returnedParameters.add(parameters.getParameter(INPUT_IMAGE)); returnedParameters.add(parameters.getParameter(INPUT_OBJECTS)); returnedParameters.add(parameters.getParameter(OUTPUT_SEPARATOR)); returnedParameters.add(parameters.getParameter(APPLY_TO_INPUT)); if (!(boolean) parameters.getValue(APPLY_TO_INPUT, workspace)) { returnedParameters.add(parameters.getParameter(ADD_OUTPUT_TO_WORKSPACE)); if ((boolean) parameters.getValue(ADD_OUTPUT_TO_WORKSPACE, workspace)) { returnedParameters.add(parameters.getParameter(OUTPUT_IMAGE)); } } returnedParameters.add(parameters.getParameter(CONTENT_SEPARATOR)); returnedParameters.add(parameters.getParameter(LABEL_MODE)); switch ((String) parameters.getValue(LABEL_MODE, workspace)) { case LabelModes.CHILD_COUNT: returnedParameters.add(parameters.getParameter(CHILD_OBJECTS_FOR_LABEL)); ((ChildObjectsP) parameters.getParameter(CHILD_OBJECTS_FOR_LABEL)) .setParentObjectsName(inputObjectsName); break; case LabelModes.MEASUREMENT_VALUE: returnedParameters.add(parameters.getParameter(MEASUREMENT_FOR_LABEL)); ((ObjectMeasurementP) parameters.getParameter(MEASUREMENT_FOR_LABEL)).setObjectName(inputObjectsName); break; case LabelModes.OBJECT_METADATA_ITEM: returnedParameters.add(parameters.getParameter(OBJECT_METADATA_FOR_LABEL)); ((ObjectMetadataP) parameters.getParameter(OBJECT_METADATA_FOR_LABEL)).setObjectName(inputObjectsName); break; case LabelModes.PARENT_ID: returnedParameters.add(parameters.getParameter(PARENT_OBJECT_FOR_LABEL)); ((ParentObjectsP) parameters.getParameter(PARENT_OBJECT_FOR_LABEL)) .setChildObjectsName(inputObjectsName); break; case LabelModes.PARENT_MEASUREMENT_VALUE: returnedParameters.add(parameters.getParameter(PARENT_OBJECT_FOR_LABEL)); ((ParentObjectsP) parameters.getParameter(PARENT_OBJECT_FOR_LABEL)) .setChildObjectsName(inputObjectsName); returnedParameters.add(parameters.getParameter(MEASUREMENT_FOR_LABEL)); if (parentObjectsName != null) { ((ObjectMeasurementP) parameters.getParameter(MEASUREMENT_FOR_LABEL)) .setObjectName(parentObjectsName); } break; case LabelModes.PARTNER_COUNT: returnedParameters.add(parameters.getParameter(PARTNER_OBJECTS_FOR_LABEL)); ((PartnerObjectsP) parameters.getParameter(PARTNER_OBJECTS_FOR_LABEL)) .setPartnerObjectsName(inputObjectsName); break; } if (!((String) parameters.getValue(LABEL_MODE, workspace)).equals(LabelModes.OBJECT_METADATA_ITEM)) { returnedParameters.add(parameters.getParameter(DECIMAL_PLACES)); returnedParameters.add(parameters.getParameter(USE_SCIENTIFIC)); } returnedParameters.add(parameters.getParameter(LABEL_SIZE)); returnedParameters.add(parameters.getParameter(X_OFFSET)); returnedParameters.add(parameters.getParameter(Y_OFFSET)); returnedParameters.add(parameters.getParameter(CENTRE_TEXT)); returnedParameters.add(parameters.getParameter(PREFIX)); returnedParameters.add(parameters.getParameter(SUFFIX)); returnedParameters.addAll(super.updateAndGetParameters(inputObjectsName)); returnedParameters.add(parameters.getParameter(LOCATION_SEPARATOR)); returnedParameters.add(parameters.getParameter(LABEL_POSITION)); switch ((String) parameters.getValue(LABEL_POSITION, workspace)) { default: returnedParameters.add(parameters.getParameter(RENDER_IN_ALL_OBJECT_SLICES)); break; case LabelPositions.FIXED_VALUE: returnedParameters.add(parameters.getParameter(X_POSITION)); returnedParameters.add(parameters.getParameter(Y_POSITION)); returnedParameters.add(parameters.getParameter(RENDER_IN_ALL_OBJECT_SLICES)); if (!(boolean) parameters.getValue(RENDER_IN_ALL_OBJECT_SLICES, workspace)) returnedParameters.add(parameters.getParameter(Z_POSITION)); break; case LabelPositions.OBJECT_MEASUREMENT: returnedParameters.add(parameters.getParameter(X_POSITION_MEASUREMENT)); returnedParameters.add(parameters.getParameter(Y_POSITION_MEASUREMENT)); ((ObjectMeasurementP) parameters.getParameter(X_POSITION_MEASUREMENT)).setObjectName(inputObjectsName); ((ObjectMeasurementP) parameters.getParameter(Y_POSITION_MEASUREMENT)).setObjectName(inputObjectsName); returnedParameters.add(parameters.getParameter(RENDER_IN_ALL_OBJECT_SLICES)); if (!(boolean) parameters.getValue(RENDER_IN_ALL_OBJECT_SLICES, workspace)) { returnedParameters.add(parameters.getParameter(Z_POSITION_MEASUREMENT)); ((ObjectMeasurementP) parameters.getParameter(Z_POSITION_MEASUREMENT)) .setObjectName(inputObjectsName); } break; } returnedParameters.add(parameters.getParameter(RENDER_IN_ALL_FRAMES)); returnedParameters.add(parameters.getParameter(EXECUTION_SEPARATOR)); returnedParameters.add(parameters.getParameter(ENABLE_MULTITHREADING)); return returnedParameters; } @Override public ImageMeasurementRefs updateAndGetImageMeasurementRefs() { return null; } @Override public ObjMeasurementRefs updateAndGetObjectMeasurementRefs() { return null; } @Override public ObjMetadataRefs updateAndGetObjectMetadataRefs() { return null; } @Override public MetadataRefs updateAndGetMetadataReferences() { return null; } @Override public ParentChildRefs updateAndGetParentChildRefs() { return null; } @Override public PartnerRefs updateAndGetPartnerRefs() { return null; } @Override public boolean verify() { return true; } @Override protected void addParameterDescriptions() { super.addParameterDescriptions(); parameters.get(INPUT_IMAGE) .setDescription("Image onto which overlay will be rendered. Input image will only be updated if \"" + APPLY_TO_INPUT + "\" is enabled, otherwise the image containing the overlay will be stored as a new image with name specified by \"" + OUTPUT_IMAGE + "\"."); parameters.get(INPUT_OBJECTS).setDescription("Objects to represent as overlays."); parameters.get(APPLY_TO_INPUT).setDescription( "Determines if the modifications made to the input image (added overlay elements) will be applied to that image or directed to a new image. When selected, the input image will be updated."); parameters.get(ADD_OUTPUT_TO_WORKSPACE).setDescription( "If the modifications (overlay) aren't being applied directly to the input image, this control will determine if a separate image containing the overlay should be saved to the workspace."); parameters.get(OUTPUT_IMAGE).setDescription( "The name of the new image to be saved to the workspace (if not applying the changes directly to the input image)."); parameters.get(LABEL_MODE).setDescription("Controls what information each label displays:
    " + "
  • \"" + LabelModes.CHILD_COUNT + "\" The number of children from a specific object collection for each object. The children to summarise are selected using the \"" + CHILD_OBJECTS_FOR_LABEL + "\" parameter.
  • " + "
  • \"" + LabelModes.ID + "\" The ID number of the object.
  • " + "
  • \"" + LabelModes.MEASUREMENT_VALUE + "\" A measurement associated with the object. The measurement is selected using the \"" + MEASUREMENT_FOR_LABEL + "\" parameter.
  • " + "
  • \"" + LabelModes.PARENT_ID + "\" The ID number of a parent of the object. The parent object is selected using the \"" + PARENT_OBJECT_FOR_LABEL + "\" parameter.
  • " + "
  • \"" + LabelModes.PARENT_MEASUREMENT_VALUE + "\" A measurement associated with a parent of the object. The measurement is selected using the \"" + MEASUREMENT_FOR_LABEL + "\" parameter and the parent object with the \"" + PARENT_OBJECT_FOR_LABEL + "\" parameter.
  • " + "
  • \"" + LabelModes.PARTNER_COUNT + "\" The number of partners from a specific object collection for each object. The partners to summarise are selected using the \"" + PARTNER_OBJECTS_FOR_LABEL + "\" parameter.
"); parameters.get(DECIMAL_PLACES) .setDescription("Number of decimal places to use when displaying numeric values."); parameters.get(USE_SCIENTIFIC).setDescription( "When enabled, numeric values will be displayed in the format 1.23E-3. Otherwise, the same value would appear as 0.00123."); parameters.get(LABEL_SIZE).setDescription("Font size of the text label."); parameters.get(X_OFFSET).setDescription( "Offset the label by this number of pixels horizontally (along the x-axis). Increasingly positive numbers move the label right."); parameters.get(Y_OFFSET).setDescription( "Offset the label by this number of pixels vertically (along the y-axis). Increasingly positive numbers move the label down."); parameters.get(PREFIX).setDescription("Text to display at beginning of every label"); parameters.get(SUFFIX).setDescription("Text to display at end of every label"); parameters.get(CHILD_OBJECTS_FOR_LABEL).setDescription("If \"" + LABEL_MODE + "\" is set to \"" + LabelModes.CHILD_COUNT + "\", these are the child objects which will be counted and displayed on the label. These objects will be children of the input objects."); parameters.get(PARENT_OBJECT_FOR_LABEL).setDescription("If \"" + LABEL_MODE + "\" is set to either \"" + LabelModes.PARENT_ID + "\" or \"" + LabelModes.PARENT_MEASUREMENT_VALUE + "\", these are the parent objects which will be used. These objects will be parents of the input objects."); parameters.get(PARTNER_OBJECTS_FOR_LABEL).setDescription("If \"" + LABEL_MODE + "\" is set to \"" + LabelModes.PARTNER_COUNT + "\", these are the partner objects which will be counted and displayed on the label. These objects will be partners of the input objects."); parameters.get(MEASUREMENT_FOR_LABEL) .setDescription("If \"" + LABEL_MODE + "\" is set to either \"" + LabelModes.MEASUREMENT_VALUE + "\" or \"" + LabelModes.PARENT_MEASUREMENT_VALUE + "\", these are the measurements which will be used."); parameters.get(LABEL_POSITION) .setDescription("Determines the method used for placing the label overlay for each object:
    " + "
  • \"" + LabelPositions.CENTRE + "\" Labels will be placed at the centroid (average coordinate location) of each object. This position won't necessarily coincide with a region corresponding to that object. For example, the centroid of a crescent shape won't lie on the crescent itself.
  • " + "
  • \"" + LabelPositions.FIXED_VALUE + "\" Labels will be placed at the x,y,z location specified by the user.
  • " + "
  • \"" + LabelPositions.INSIDE + "\" Labels will be placed coincident with the largest region of each object. This ensures the label is placed directly over the relevant object.
" + "
  • \"" + LabelPositions.OBJECT_MEASUREMENT + "\" Labels will be placed coincident with the specified measurements for each object.
  • "); parameters.get(X_POSITION_MEASUREMENT).setDescription( "Object measurement specifying the X-position of the label. Measurement value must be specified in pixel units."); parameters.get(Y_POSITION_MEASUREMENT).setDescription( "Object measurement specifying the Y-position of the label. Measurement value must be specified in pixel units."); parameters.get(Z_POSITION_MEASUREMENT).setDescription( "Object measurement specifying the Z-position (slice) of the label. Measurement value must be specified in slice units."); parameters.get(X_POSITION).setDescription( "Fixed value specifying the X-position of the label. Specified in pixel units."); parameters.get(Y_POSITION).setDescription( "Fixed value specifying the Y-position of the label. Specified in pixel units."); parameters.get(Z_POSITION).setDescription( "Fixed value specifying the Z-position of the label. Specified in pixel units."); parameters.get(RENDER_IN_ALL_OBJECT_SLICES) .setDescription("Display overlay elements in all slices corresponding to that object."); parameters.get(RENDER_IN_ALL_FRAMES).setDescription( "Display overlay elements in all frames, irrespective of whether each object is present in that frame."); parameters.get(ENABLE_MULTITHREADING).setDescription( "Process multiple overlay elements simultaneously. This can provide a speed improvement when working on a computer with a multi-core CPU."); } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy