Search in sources :

Example 21 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class TileClassificationsToAnnotationsPlugin method getDefaultParameterList.

@Override
public ParameterList getDefaultParameterList(final ImageData<T> imageData) {
    if (!parametersInitialized) {
        Set<PathClass> pathClasses = PathClassifierTools.getRepresentedPathClasses(imageData.getHierarchy(), PathTileObject.class);
        List<PathClass> choices = new ArrayList<>(pathClasses);
        Collections.sort(choices, new Comparator<PathClass>() {

            @Override
            public int compare(PathClass pc1, PathClass pc2) {
                return pc1.getName().compareTo(pc2.getName());
            }
        });
        PathClass allClasses = PathClassFactory.getPathClass("All classes");
        PathClass defaultChoice = allClasses;
        choices.add(0, allClasses);
        // PathClass classTumor = PathClassFactory.getDefaultPathClass(PathClasses.TUMOR); // Tumor is the most likely choice, so default to it if available
        // PathClass defaultChoice = choices.contains(classTumor) ? classTumor : choices.get(0);
        params = new ParameterList();
        params.addChoiceParameter("pathClass", "Choose class", defaultChoice, choices, "Choose PathClass to create annotations from").addBooleanParameter("deleteTiles", "Delete existing child objects", false, "Delete the tiles that were used for creating annotations - further training will not be possible after these are deleted").addBooleanParameter("clearAnnotations", "Clear existing annotations", true, "Remove all existing annotations (often a good idea if they were used to train a classifier, but are no longer needed)").addBooleanParameter("splitAnnotations", "Split new annotations", false, "Split newly-created annotations into distinct regions (rather than have one large, possibly-discontinuous object)");
    // .addDoubleParameter("simplify", "Simplify shapes", 0);
    }
    return params;
}
Also used : PathClass(qupath.lib.objects.classes.PathClass) ArrayList(java.util.ArrayList) ParameterList(qupath.lib.plugins.parameters.ParameterList)

Example 22 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class CoherenceFeaturePlugin method addRunnableTasks.

@Override
protected void addRunnableTasks(final ImageData<BufferedImage> imageData, final PathObject parentObject, List<Runnable> tasks) {
    final ParameterList params = getParameterList(imageData);
    final ImageServer<BufferedImage> server = imageData.getServer();
    tasks.add(new CoherenceRunnable(server, parentObject, params, imageData.getColorDeconvolutionStains()));
}
Also used : ParameterList(qupath.lib.plugins.parameters.ParameterList) BufferedImage(java.awt.image.BufferedImage)

Example 23 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class IntensityFeaturesPlugin method processObject.

static boolean processObject(final PathObject pathObject, final ParameterList params, final ImageData<BufferedImage> imageData) throws IOException {
    // Determine amount to downsample
    var server = imageData.getServer();
    var stains = imageData.getColorDeconvolutionStains();
    PixelCalibration cal = server.getPixelCalibration();
    double downsample = calculateDownsample(cal, params);
    if (downsample <= 0) {
        logger.warn("Effective downsample must be > 0 (requested value {})", downsample);
    }
    // Determine region shape
    RegionType regionType = (RegionType) params.getChoiceParameterValue("region");
    // Try to get ROI
    boolean useROI = regionType == RegionType.ROI || regionType == RegionType.NUCLEUS;
    ROI roi = null;
    if (regionType == RegionType.NUCLEUS) {
        if (pathObject instanceof PathCellObject)
            roi = ((PathCellObject) pathObject).getNucleusROI();
    } else
        roi = pathObject.getROI();
    // pathROI = ((PathCellObject)pathObject).getNucleusROI();
    if (roi == null)
        return false;
    // Create a map - this is useful for occasions when tiling is needed
    Map<FeatureColorTransform, List<FeatureComputer>> map = new LinkedHashMap<>();
    if (server.isRGB()) {
        for (FeatureColorTransform transform : FeatureColorTransformEnum.values()) {
            List<FeatureComputer> list = new ArrayList<>();
            map.put(transform, list);
            for (FeatureComputerBuilder builder : builders) {
                list.add(builder.build());
            }
        }
    } else {
        for (FeatureColorTransform transform : getBasicChannelTransforms(server.nChannels())) {
            List<FeatureComputer> list = new ArrayList<>();
            map.put(transform, list);
            for (FeatureComputerBuilder builder : builders) {
                list.add(builder.build());
            }
        }
    }
    String prefix = getDiameterString(server, params);
    // Create tiled ROIs, if required
    ImmutableDimension sizePreferred = ImmutableDimension.getInstance((int) (2000 * downsample), (int) (2000 * downsample));
    // ImmutableDimension sizePreferred = new ImmutableDimension((int)(200*downsample), (int)(200*downsample));
    Collection<? extends ROI> rois = RoiTools.computeTiledROIs(roi, sizePreferred, sizePreferred, false, 0);
    if (rois.size() > 1)
        logger.info("Splitting {} into {} tiles for intensity measurements", roi, rois.size());
    for (ROI pathROI : rois) {
        if (Thread.currentThread().isInterrupted()) {
            logger.warn("Measurement skipped - thread interrupted!");
            return false;
        }
        // Get bounds
        RegionRequest region;
        if (useROI) {
            region = RegionRequest.createInstance(server.getPath(), downsample, pathROI);
        } else {
            ImmutableDimension size = getPreferredTileSizePixels(server, params);
            // RegionRequest region = RegionRequest.createInstance(server.getPath(), downsample, (int)(pathROI.getCentroidX() + .5) - size.width/2, (int)(pathROI.getCentroidY() + .5) - size.height/2, size.width, size.height, pathROI.getT(), pathROI.getZ());
            // Try to align with pixel boundaries according to the downsample being used - otherwise, interpolation can cause some strange, pattern artefacts
            int xStart = (int) (Math.round(pathROI.getCentroidX() / downsample) * downsample) - size.width / 2;
            int yStart = (int) (Math.round(pathROI.getCentroidY() / downsample) * downsample) - size.height / 2;
            int width = Math.min(server.getWidth(), xStart + size.width) - xStart;
            int height = Math.min(server.getHeight(), yStart + size.height) - yStart;
            region = RegionRequest.createInstance(server.getPath(), downsample, xStart, yStart, width, height, pathROI.getT(), pathROI.getZ());
        }
        // // Check image large enough to do *anything* of value
        // if (region.getWidth() / downsample < 1 || region.getHeight() / downsample < 1) {
        // logger.trace("Requested region is too small! {}", region);
        // return false;
        // }
        // System.out.println(bounds);
        // System.out.println("Size: " + size);
        BufferedImage img = server.readBufferedImage(region);
        if (img == null) {
            logger.error("Could not read image - unable to compute intensity features for {}", pathObject);
            return false;
        }
        // Create mask ROI if necessary
        // If we just have 1 pixel, we want to use it so that the mean/min/max measurements are valid (even if nothing else is)
        byte[] maskBytes = null;
        if (useROI && img.getWidth() * img.getHeight() > 1) {
            BufferedImage imgMask = BufferedImageTools.createROIMask(img.getWidth(), img.getHeight(), pathROI, region);
            maskBytes = ((DataBufferByte) imgMask.getRaster().getDataBuffer()).getData();
        }
        boolean isRGB = server.isRGB();
        List<FeatureColorTransform> transforms;
        if (isRGB)
            transforms = Arrays.asList(FeatureColorTransformEnum.values());
        else
            transforms = getBasicChannelTransforms(server.nChannels());
        int w = img.getWidth();
        int h = img.getHeight();
        int[] rgbBuffer = isRGB ? img.getRGB(0, 0, w, h, null, 0, w) : null;
        float[] pixels = null;
        for (FeatureColorTransform transform : transforms) {
            // Check if the color transform is requested
            if (params.containsKey(transform.getKey()) && Boolean.TRUE.equals(params.getBooleanParameterValue(transform.getKey()))) {
                // Transform the pixels
                pixels = transform.getTransformedPixels(img, rgbBuffer, stains, pixels);
                // Create the simple image
                SimpleModifiableImage pixelImage = SimpleImages.createFloatImage(pixels, w, h);
                // Apply any arbitrary mask
                if (maskBytes != null) {
                    for (int i = 0; i < pixels.length; i++) {
                        if (maskBytes[i] == (byte) 0)
                            pixelImage.setValue(i % w, i / w, Float.NaN);
                    }
                } else if (regionType == RegionType.CIRCLE) {
                    // Apply circular tile mask
                    double cx = (w - 1) / 2;
                    double cy = (h - 1) / 2;
                    double radius = Math.max(w, h) * .5;
                    double distThreshold = radius * radius;
                    for (int y = 0; y < h; y++) {
                        for (int x = 0; x < w; x++) {
                            if ((cx - x) * (cx - x) + (cy - y) * (cy - y) > distThreshold)
                                pixelImage.setValue(x, y, Float.NaN);
                        }
                    }
                }
                // Do the computations
                for (FeatureComputer computer : map.get(transform)) {
                    computer.updateFeatures(pixelImage, transform, params);
                }
            }
        }
    }
    // Add measurements to the parent object
    for (Entry<FeatureColorTransform, List<FeatureComputer>> entry : map.entrySet()) {
        String name = prefix + ": " + entry.getKey().getName(imageData, false) + ":";
        for (FeatureComputer computer : entry.getValue()) computer.addMeasurements(pathObject, name, params);
    }
    pathObject.getMeasurementList().close();
    // Lock any measurements that require it
    if (pathObject instanceof PathAnnotationObject)
        ((PathAnnotationObject) pathObject).setLocked(true);
    else if (pathObject instanceof TMACoreObject)
        ((TMACoreObject) pathObject).setLocked(true);
    return true;
}
Also used : ArrayList(java.util.ArrayList) BufferedImage(java.awt.image.BufferedImage) LinkedHashMap(java.util.LinkedHashMap) HaralickFeatureComputer(qupath.lib.analysis.features.HaralickFeatureComputer) SimpleModifiableImage(qupath.lib.analysis.images.SimpleModifiableImage) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) ArrayList(java.util.ArrayList) MeasurementList(qupath.lib.measurements.MeasurementList) ParameterList(qupath.lib.plugins.parameters.ParameterList) List(java.util.List) TMACoreObject(qupath.lib.objects.TMACoreObject) PixelCalibration(qupath.lib.images.servers.PixelCalibration) ROI(qupath.lib.roi.interfaces.ROI) ImmutableDimension(qupath.lib.geom.ImmutableDimension) RegionRequest(qupath.lib.regions.RegionRequest) PathCellObject(qupath.lib.objects.PathCellObject)

Example 24 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class IntensityFeaturesPlugin method addRunnableTasks.

@Override
protected void addRunnableTasks(final ImageData<BufferedImage> imageData, final PathObject parentObject, List<Runnable> tasks) {
    final ParameterList params = getParameterList(imageData);
    final ImageServer<BufferedImage> server = imageData.getServer();
    // Don't add any tasks if the downsample isn't value
    PixelCalibration cal = server.getPixelCalibration();
    double downsample = calculateDownsample(cal, params);
    if (downsample <= 0) {
        throw new IllegalArgumentException("Effective downsample must be > 0 (requested value " + GeneralTools.formatNumber(downsample, 1) + ")");
    }
    tasks.add(new IntensityFeatureRunnable(imageData, parentObject, params));
}
Also used : ParameterList(qupath.lib.plugins.parameters.ParameterList) PixelCalibration(qupath.lib.images.servers.PixelCalibration) BufferedImage(java.awt.image.BufferedImage)

Example 25 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class LocalBinaryPatternsPlugin method addRunnableTasks.

@Override
protected void addRunnableTasks(final ImageData<BufferedImage> imageData, final PathObject parentObject, List<Runnable> tasks) {
    final ParameterList params = getParameterList(imageData);
    final ImageServer<BufferedImage> server = imageData.getServer();
    tasks.add(new LBFRunnable(server, parentObject, params, imageData.getColorDeconvolutionStains()));
}
Also used : ParameterList(qupath.lib.plugins.parameters.ParameterList) BufferedImage(java.awt.image.BufferedImage)

Aggregations

ParameterList (qupath.lib.plugins.parameters.ParameterList)53 BufferedImage (java.awt.image.BufferedImage)15 ArrayList (java.util.ArrayList)13 IOException (java.io.IOException)11 List (java.util.List)9 Collectors (java.util.stream.Collectors)8 BorderPane (javafx.scene.layout.BorderPane)8 PathObject (qupath.lib.objects.PathObject)8 Logger (org.slf4j.Logger)7 LoggerFactory (org.slf4j.LoggerFactory)7 GeneralTools (qupath.lib.common.GeneralTools)7 Dialogs (qupath.lib.gui.dialogs.Dialogs)7 ImageServer (qupath.lib.images.servers.ImageServer)7 Insets (javafx.geometry.Insets)6 Tooltip (javafx.scene.control.Tooltip)6 Collection (java.util.Collection)5 Map (java.util.Map)5 SimpleStringProperty (javafx.beans.property.SimpleStringProperty)5 ContextMenu (javafx.scene.control.ContextMenu)5 Label (javafx.scene.control.Label)5