Search in sources :

Example 26 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class ImageDetailsPane method promptToSetPixelSize.

static boolean promptToSetPixelSize(ImageData<BufferedImage> imageData, boolean requestZSpacing) {
    var server = imageData.getServer();
    var hierarchy = imageData.getHierarchy();
    var selected = hierarchy.getSelectionModel().getSelectedObject();
    var roi = selected == null ? null : selected.getROI();
    PixelCalibration cal = server.getPixelCalibration();
    double pixelWidthMicrons = cal.getPixelWidthMicrons();
    double pixelHeightMicrons = cal.getPixelHeightMicrons();
    double zSpacingMicrons = cal.getZSpacingMicrons();
    // Use line or area ROI if possible
    if (!requestZSpacing && roi != null && !roi.isEmpty() && (roi.isArea() || roi.isLine())) {
        boolean setPixelHeight = true;
        boolean setPixelWidth = true;
        String message;
        String units = GeneralTools.micrometerSymbol();
        double pixelWidth = cal.getPixelWidthMicrons();
        double pixelHeight = cal.getPixelHeightMicrons();
        if (!Double.isFinite(pixelWidth))
            pixelWidth = 1;
        if (!Double.isFinite(pixelHeight))
            pixelHeight = 1;
        Double defaultValue = null;
        if (roi.isLine()) {
            setPixelHeight = roi.getBoundsHeight() != 0;
            setPixelWidth = roi.getBoundsWidth() != 0;
            message = "Enter selected line length";
            defaultValue = roi.getScaledLength(pixelWidth, pixelHeight);
        } else {
            message = "Enter selected ROI area";
            units = units + "^2";
            defaultValue = roi.getScaledArea(pixelWidth, pixelHeight);
        }
        // }
        if (Double.isNaN(defaultValue))
            defaultValue = 1.0;
        var params = new ParameterList().addDoubleParameter("inputValue", message, defaultValue, units, "Enter calibrated value in " + units + " for the selected ROI to calculate the pixel size").addBooleanParameter("squarePixels", "Assume square pixels", true, "Set the pixel width to match the pixel height");
        params.setHiddenParameters(setPixelHeight && setPixelWidth, "squarePixels");
        if (!Dialogs.showParameterDialog("Set pixel size", params))
            return false;
        Double result = params.getDoubleParameterValue("inputValue");
        setPixelHeight = setPixelHeight || params.getBooleanParameterValue("squarePixels");
        setPixelWidth = setPixelWidth || params.getBooleanParameterValue("squarePixels");
        // Double result = Dialogs.showInputDialog("Set pixel size", message, defaultValue);
        // if (result == null)
        // return false;
        double sizeMicrons;
        if (roi.isLine())
            sizeMicrons = result.doubleValue() / roi.getLength();
        else
            sizeMicrons = Math.sqrt(result.doubleValue() / roi.getArea());
        if (setPixelHeight)
            pixelHeightMicrons = sizeMicrons;
        if (setPixelWidth)
            pixelWidthMicrons = sizeMicrons;
    } else {
        // Prompt for all required values
        ParameterList params = new ParameterList().addDoubleParameter("pixelWidth", "Pixel width", pixelWidthMicrons, GeneralTools.micrometerSymbol(), "Enter the pixel width").addDoubleParameter("pixelHeight", "Pixel height", pixelHeightMicrons, GeneralTools.micrometerSymbol(), "Entry the pixel height").addDoubleParameter("zSpacing", "Z-spacing", zSpacingMicrons, GeneralTools.micrometerSymbol(), "Enter the spacing between slices of a z-stack");
        params.setHiddenParameters(server.nZSlices() == 1, "zSpacing");
        if (!Dialogs.showParameterDialog("Set pixel size", params))
            return false;
        if (server.nZSlices() != 1) {
            zSpacingMicrons = params.getDoubleParameterValue("zSpacing");
        }
        pixelWidthMicrons = params.getDoubleParameterValue("pixelWidth");
        pixelHeightMicrons = params.getDoubleParameterValue("pixelHeight");
    }
    if ((pixelWidthMicrons <= 0 || pixelHeightMicrons <= 0) || (server.nZSlices() > 1 && zSpacingMicrons <= 0)) {
        if (!Dialogs.showConfirmDialog("Set pixel size", "You entered values <= 0, do you really want to remove this pixel calibration information?")) {
            return false;
        }
        zSpacingMicrons = server.nZSlices() > 1 && zSpacingMicrons > 0 ? zSpacingMicrons : Double.NaN;
        if (pixelWidthMicrons <= 0 || pixelHeightMicrons <= 0) {
            pixelWidthMicrons = Double.NaN;
            pixelHeightMicrons = Double.NaN;
        }
    }
    if (QP.setPixelSizeMicrons(imageData, pixelWidthMicrons, pixelHeightMicrons, zSpacingMicrons)) {
        // Log for scripts
        WorkflowStep step;
        if (server.nZSlices() == 1) {
            var map = Map.of("pixelWidthMicrons", pixelWidthMicrons, "pixelHeightMicrons", pixelHeightMicrons);
            String script = String.format("setPixelSizeMicrons(%f, %f)", pixelWidthMicrons, pixelHeightMicrons);
            step = new DefaultScriptableWorkflowStep("Set pixel size " + GeneralTools.micrometerSymbol(), map, script);
        } else {
            var map = Map.of("pixelWidthMicrons", pixelWidthMicrons, "pixelHeightMicrons", pixelHeightMicrons, "zSpacingMicrons", zSpacingMicrons);
            String script = String.format("setPixelSizeMicrons(%f, %f, %f)", pixelWidthMicrons, pixelHeightMicrons, zSpacingMicrons);
            step = new DefaultScriptableWorkflowStep("Set pixel size " + GeneralTools.micrometerSymbol(), map, script);
        }
        imageData.getHistoryWorkflow().addStep(step);
        return true;
    } else
        return false;
}
Also used : DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) ParameterList(qupath.lib.plugins.parameters.ParameterList) PixelCalibration(qupath.lib.images.servers.PixelCalibration)

Example 27 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class ImageDetailsPane method getValue.

private Object getValue(ImageDetailRow rowType) {
    if (imageData == null)
        return null;
    ImageServer<BufferedImage> server = imageData.getServer();
    PixelCalibration cal = server.getPixelCalibration();
    switch(rowType) {
        case NAME:
            var project = QuPathGUI.getInstance().getProject();
            var entry = project == null ? null : project.getEntry(imageData);
            if (entry == null)
                return ServerTools.getDisplayableImageName(server);
            else
                return entry.getImageName();
        case URI:
            Collection<URI> uris = server.getURIs();
            if (uris.isEmpty())
                return "Not available";
            if (uris.size() == 1)
                return decodeURI(uris.iterator().next());
            return "[" + String.join(", ", uris.stream().map(ImageDetailsPane::decodeURI).collect(Collectors.toList())) + "]";
        case IMAGE_TYPE:
            return imageData.getImageType();
        case METADATA_CHANGED:
            return hasOriginalMetadata(imageData.getServer()) ? "No" : "Yes";
        case PIXEL_TYPE:
            String type = server.getPixelType().toString().toLowerCase();
            if (server.isRGB())
                type += " (rgb)";
            return type;
        case MAGNIFICATION:
            double mag = server.getMetadata().getMagnification();
            if (Double.isNaN(mag))
                return "Unknown";
            return mag;
        case WIDTH:
            if (cal.hasPixelSizeMicrons())
                return String.format("%s px (%.2f %s)", server.getWidth(), server.getWidth() * cal.getPixelWidthMicrons(), GeneralTools.micrometerSymbol());
            else
                return String.format("%s px", server.getWidth());
        case HEIGHT:
            if (cal.hasPixelSizeMicrons())
                return String.format("%s px (%.2f %s)", server.getHeight(), server.getHeight() * cal.getPixelHeightMicrons(), GeneralTools.micrometerSymbol());
            else
                return String.format("%s px", server.getHeight());
        case DIMENSIONS:
            return String.format("%d x %d x %d", server.nChannels(), server.nZSlices(), server.nTimepoints());
        case PIXEL_WIDTH:
            if (cal.hasPixelSizeMicrons())
                return String.format("%.4f %s", cal.getPixelWidthMicrons(), GeneralTools.micrometerSymbol());
            else
                return "Unknown";
        case PIXEL_HEIGHT:
            if (cal.hasPixelSizeMicrons())
                return String.format("%.4f %s", cal.getPixelHeightMicrons(), GeneralTools.micrometerSymbol());
            else
                return "Unknown";
        case Z_SPACING:
            if (cal.hasZSpacingMicrons())
                return String.format("%.4f %s", cal.getZSpacingMicrons(), GeneralTools.micrometerSymbol());
            else
                return "Unknown";
        case UNCOMPRESSED_SIZE:
            double size = server.getWidth() / 1024.0 * server.getHeight() / 1024.0 * server.getPixelType().getBytesPerPixel() * server.nChannels() * server.nZSlices() * server.nTimepoints();
            String units = " MB";
            if (size > 1000) {
                size /= 1024.0;
                units = " GB";
            }
            return GeneralTools.formatNumber(size, 1) + units;
        case SERVER_TYPE:
            return server.getServerType();
        case PYRAMID:
            if (server.nResolutions() == 1)
                return "No";
            return GeneralTools.arrayToString(Locale.getDefault(Locale.Category.FORMAT), server.getPreferredDownsamples(), 1);
        case STAIN_1:
            return imageData.getColorDeconvolutionStains().getStain(1);
        case STAIN_2:
            return imageData.getColorDeconvolutionStains().getStain(2);
        case STAIN_3:
            return imageData.getColorDeconvolutionStains().getStain(3);
        case BACKGROUND:
            ColorDeconvolutionStains stains = imageData.getColorDeconvolutionStains();
            double[] whitespace = new double[] { stains.getMaxRed(), stains.getMaxGreen(), stains.getMaxBlue() };
            return whitespace;
        default:
            return null;
    }
}
Also used : PixelCalibration(qupath.lib.images.servers.PixelCalibration) URI(java.net.URI) BufferedImage(java.awt.image.BufferedImage) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains)

Example 28 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class DilateAnnotationPlugin method getTasks.

@Override
protected Collection<Runnable> getTasks(final PluginRunner<T> runner) {
    Collection<? extends PathObject> parentObjects = getParentObjects(runner);
    if (parentObjects == null || parentObjects.isEmpty())
        return Collections.emptyList();
    // Add a single task, to avoid multithreading - which may complicate setting parents
    List<Runnable> tasks = new ArrayList<>(parentObjects.size());
    ImageServer<T> server = getServer(runner);
    Rectangle bounds = new Rectangle(0, 0, server.getWidth(), server.getHeight());
    PathObjectHierarchy hierarchy = getHierarchy(runner);
    double radiusPixels;
    PixelCalibration cal = server.getPixelCalibration();
    if (cal.hasPixelSizeMicrons())
        radiusPixels = params.getDoubleParameterValue("radiusMicrons") / cal.getAveragedPixelSizeMicrons();
    else
        radiusPixels = params.getDoubleParameterValue("radiusPixels");
    boolean constrainToParent = params.getBooleanParameterValue("constrainToParent");
    boolean removeInterior = params.getBooleanParameterValue("removeInterior");
    LineCap cap = params.containsKey("lineCap") ? (LineCap) params.getChoiceParameterValue("lineCap") : LineCap.ROUND;
    // Want to reset selection
    PathObject selected = hierarchy.getSelectionModel().getSelectedObject();
    Collection<PathObject> previousSelection = new ArrayList<>(hierarchy.getSelectionModel().getSelectedObjects());
    tasks.add(() -> {
        for (PathObject pathObject : parentObjects) {
            addExpandedAnnotation(bounds, hierarchy, pathObject, radiusPixels, constrainToParent, removeInterior, cap);
        }
        hierarchy.getSelectionModel().selectObjects(previousSelection);
        hierarchy.getSelectionModel().setSelectedObject(selected, true);
    });
    return tasks;
}
Also used : PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) PixelCalibration(qupath.lib.images.servers.PixelCalibration) PathObject(qupath.lib.objects.PathObject)

Example 29 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class ShapeFeaturesPlugin method addRunnableTasks.

@Override
protected void addRunnableTasks(final ImageData<T> imageData, final PathObject parentObject, List<Runnable> tasks) {
    PixelCalibration cal = imageData == null ? null : imageData.getServer().getPixelCalibration();
    boolean useMicrons = params.getBooleanParameterValue("useMicrons") && cal != null && cal.hasPixelSizeMicrons();
    double pixelWidth = useMicrons ? cal.getPixelWidthMicrons() : 1;
    double pixelHeight = useMicrons ? cal.getPixelHeightMicrons() : 1;
    String unit = useMicrons ? GeneralTools.micrometerSymbol() : "px";
    boolean doArea = params.getBooleanParameterValue("area");
    boolean doPerimeter = params.getBooleanParameterValue("perimeter");
    boolean doCircularity = params.getBooleanParameterValue("circularity");
    ROI roi = (parentObject.hasROI() && parentObject.getROI().isArea()) ? parentObject.getROI() : null;
    if (roi != null) {
        tasks.add(new Runnable() {

            @Override
            public void run() {
                try {
                    MeasurementList measurementList = parentObject.getMeasurementList();
                    ROI roi;
                    if (parentObject instanceof PathCellObject) {
                        roi = ((PathCellObject) parentObject).getNucleusROI();
                        if (roi != null && roi.isArea())
                            addMeasurements(measurementList, roi, "Nucleus Shape: ", pixelWidth, pixelHeight, unit, doArea, doPerimeter, doCircularity);
                        roi = parentObject.getROI();
                        if (roi != null && roi.isArea())
                            addMeasurements(measurementList, roi, "Cell Shape: ", pixelWidth, pixelHeight, unit, doArea, doPerimeter, doCircularity);
                    } else {
                        roi = parentObject.getROI();
                        if (roi != null && roi.isArea())
                            addMeasurements(measurementList, roi, "ROI Shape: ", pixelWidth, pixelHeight, unit, doArea, doPerimeter, doCircularity);
                    }
                    measurementList.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    throw (e);
                }
            }
        });
    }
}
Also used : MeasurementList(qupath.lib.measurements.MeasurementList) PixelCalibration(qupath.lib.images.servers.PixelCalibration) ROI(qupath.lib.roi.interfaces.ROI) PathCellObject(qupath.lib.objects.PathCellObject)

Example 30 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class SmoothFeaturesPlugin method addRunnableTasks.

@Override
protected void addRunnableTasks(final ImageData<T> imageData, final PathObject parentObject, List<Runnable> tasks) {
    double fwhm;
    ImageServer<T> server = imageData.getServer();
    String fwhmStringTemp;
    PixelCalibration cal = server == null ? null : server.getPixelCalibration();
    if (cal != null && cal.hasPixelSizeMicrons()) {
        fwhm = getParameterList(imageData).getDoubleParameterValue("fwhmMicrons");
        fwhmStringTemp = GeneralTools.createFormatter(2).format(fwhm) + " " + GeneralTools.micrometerSymbol();
        fwhm /= cal.getAveragedPixelSizeMicrons();
    // params.addDoubleParameter("fwhmPixels", "Radius (FWHM)", fwhm, "pixels"); // Set the FWHM in pixels too
    } else {
        fwhm = getParameterList(imageData).getDoubleParameterValue("fwhmPixels");
        fwhmStringTemp = GeneralTools.createFormatter(2).format(fwhm) + " px";
    }
    // sigma = 50;
    final String fwhmString = fwhmStringTemp;
    final double fwhmPixels = fwhm;
    final boolean withinClass = params.getBooleanParameterValue("smoothWithinClasses");
    final boolean useLegacyNames = params.containsKey("useLegacyNames") && Boolean.TRUE.equals(params.getBooleanParameterValue("useLegacyNames"));
    tasks.add(new Runnable() {

        @Override
        public void run() {
            try {
                if (!parentObject.hasChildren())
                    return;
                // System.out.println("Smoothing with FWHM " +fwhmPixels);
                // TODO: MAKE A MORE ELEGANT LIST!!!!
                List<PathObject> pathObjects = PathObjectTools.getFlattenedObjectList(parentObject, null, false);
                Iterator<PathObject> iterObjects = pathObjects.iterator();
                while (iterObjects.hasNext()) {
                    PathObject temp = iterObjects.next();
                    if (!(temp instanceof PathDetectionObject || temp instanceof PathTileObject))
                        iterObjects.remove();
                }
                if (pathObjects.isEmpty())
                    return;
                // TODO: ACCESS & USE THE CLASSIFIER DATA!!!!
                List<String> measurements = new ArrayList<>(PathClassifierTools.getAvailableFeatures(pathObjects));
                Iterator<String> iter = measurements.iterator();
                while (iter.hasNext()) {
                    String name = iter.next().toLowerCase();
                    if (name.endsWith("smoothed") || name.startsWith("smoothed") || name.contains(" - smoothed (fwhm ") || name.startsWith("smoothed denominator (local density, ") || name.startsWith("nearby detection counts"))
                        iter.remove();
                }
                logger.debug(String.format("Smooth features: %s (FWHM: %.2f px)", parentObject.getDisplayedName(), fwhmPixels));
                smoothMeasurements(pathObjects, measurements, fwhmPixels, fwhmString, withinClass, useLegacyNames);
            // // REMOVE - the purpose was to test a 'difference of Gaussians' type of thing
            // List<String> namesAdded1 = new ArrayList<>(smoothMeasurements(pathObjects, measurements, fwhmPixels));
            // List<String> namesAdded2 = new ArrayList<>(smoothMeasurements(pathObjects, measurements, fwhmPixels * 2));
            // for (PathObject pathObject : pathObjects) {
            // MeasurementList ml = pathObject.getMeasurementList();
            // ml.ensureListOpen();
            // for (int i = 0; i < namesAdded1.size(); i++) {
            // String name1 = namesAdded1.get(i);
            // String name2 = namesAdded2.get(i);
            // double m1 = ml.getMeasurementValue(name1);
            // double m2 = ml.getMeasurementValue(name2);
            // ml.addMeasurement(name1 + " - " + name2, m1 - m2);
            // }
            // ml.closeList();
            // }
            } catch (Exception e) {
                e.printStackTrace();
                throw (e);
            }
        }
    });
}
Also used : PathDetectionObject(qupath.lib.objects.PathDetectionObject) PixelCalibration(qupath.lib.images.servers.PixelCalibration) PathTileObject(qupath.lib.objects.PathTileObject) PathObject(qupath.lib.objects.PathObject) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) MeasurementList(qupath.lib.measurements.MeasurementList) ParameterList(qupath.lib.plugins.parameters.ParameterList) List(java.util.List)

Aggregations

PixelCalibration (qupath.lib.images.servers.PixelCalibration)31 BufferedImage (java.awt.image.BufferedImage)9 ArrayList (java.util.ArrayList)8 ROI (qupath.lib.roi.interfaces.ROI)8 RegionRequest (qupath.lib.regions.RegionRequest)7 MeasurementList (qupath.lib.measurements.MeasurementList)6 PathObject (qupath.lib.objects.PathObject)6 Calibration (ij.measure.Calibration)5 PathCellObject (qupath.lib.objects.PathCellObject)5 ParameterList (qupath.lib.plugins.parameters.ParameterList)5 List (java.util.List)4 Collection (java.util.Collection)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ImagePlus (ij.ImagePlus)2 ByteProcessor (ij.process.ByteProcessor)2 FloatProcessor (ij.process.FloatProcessor)2 ImageProcessor (ij.process.ImageProcessor)2 Graphics2D (java.awt.Graphics2D)2 LinkedHashMap (java.util.LinkedHashMap)2