Search in sources :

Example 21 with MeasurementList

use of qupath.lib.measurements.MeasurementList 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 22 with MeasurementList

use of qupath.lib.measurements.MeasurementList 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)

Example 23 with MeasurementList

use of qupath.lib.measurements.MeasurementList in project qupath by qupath.

the class LocalBinaryPatternsPlugin method processObject.

static boolean processObject(final PathObject pathObject, final ParameterList params, final ImageServer<BufferedImage> server, final ColorDeconvolutionStains stains) throws InterruptedException, IOException {
    String stainsName = (String) params.getChoiceParameterValue("stainChoice");
    double mag = params.getDoubleParameterValue("magnification");
    // int d = params.getIntParameterValue("haralickDistance");
    boolean includeStats = params.getBooleanParameterValue("includeStats");
    boolean doCircular = params.getBooleanParameterValue("doCircular");
    double downsample = server.getMetadata().getMagnification() / mag;
    ROI pathROI = pathObject.getROI();
    if (pathROI == null)
        return false;
    // Get bounds
    ImmutableDimension size = getPreferredTileSizePixels(server, params);
    if (size.getWidth() / downsample < 1 || size.getHeight() / downsample < 1)
        return false;
    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());
    // System.out.println(bounds);
    // System.out.println("Size: " + size);
    BufferedImage img = server.readBufferedImage(region);
    // System.out.println("Image size: " + img.getWidth() + " x " + img.getHeight() + " pixels");
    // Get a buffer containing the image pixels
    int w = img.getWidth();
    int h = img.getHeight();
    int[] buf = img.getRGB(0, 0, w, h, null, 0, w);
    // Create a color transformer to get the images we need
    float[] pixels = new float[buf.length];
    SimpleModifiableImage pxImg = SimpleImages.createFloatImage(pixels, w, h);
    MeasurementList measurementList = pathObject.getMeasurementList();
    String postfix = " (" + getDiameterString(server, params) + ")";
    if (stainsName.equals("H-DAB")) {
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_DAB, stains, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "DAB" + postfix, ColorTransformer.ColorTransformMethod.DAB_H_DAB, stains, includeStats, doCircular);
    } else if (stainsName.equals("H&E")) {
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_E, stains, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Eosin" + postfix, ColorTransformer.ColorTransformMethod.Eosin_H_E, stains, includeStats, doCircular);
    } else if (stainsName.equals("H-DAB (8-bit)")) {
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin 8-bit" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_DAB_8_bit, stains, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "DAB 8-bit" + postfix, ColorTransformer.ColorTransformMethod.DAB_H_DAB_8_bit, stains, includeStats, doCircular);
    } else if (stainsName.equals("H&E (8-bit)")) {
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin 8-bit" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_E_8_bit, stains, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Eosin 8-bit" + postfix, ColorTransformer.ColorTransformMethod.Eosin_H_E_8_bit, stains, includeStats, doCircular);
    } else if (stainsName.equals("Optical density")) {
        processTransformedImage(pxImg, buf, pixels, measurementList, "OD sum" + postfix, ColorTransformer.ColorTransformMethod.Optical_density_sum, stains, includeStats, doCircular);
    } else if (stainsName.equals("RGB")) {
        processTransformedImage(pxImg, buf, pixels, measurementList, "Red" + postfix, ColorTransformer.ColorTransformMethod.Red, stains, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Green" + postfix, ColorTransformer.ColorTransformMethod.Green, stains, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Blue" + postfix, ColorTransformer.ColorTransformMethod.Blue, stains, includeStats, doCircular);
    } else if (stainsName.equals("Grayscale")) {
        processTransformedImage(pxImg, buf, pixels, measurementList, "Grayscale" + postfix, ColorTransformer.ColorTransformMethod.RGB_mean, stains, includeStats, doCircular);
    }
    measurementList.close();
    return true;
}
Also used : SimpleModifiableImage(qupath.lib.analysis.images.SimpleModifiableImage) MeasurementList(qupath.lib.measurements.MeasurementList) ImmutableDimension(qupath.lib.geom.ImmutableDimension) ROI(qupath.lib.roi.interfaces.ROI) RegionRequest(qupath.lib.regions.RegionRequest) BufferedImage(java.awt.image.BufferedImage)

Example 24 with MeasurementList

use of qupath.lib.measurements.MeasurementList in project qupath by qupath.

the class TMAExplorer method createAndShowStage.

private void createAndShowStage() {
    Project<BufferedImage> project = qupath.getProject();
    entries.clear();
    if (project != null) {
        // Create an output directory for the images
        File dirBaseImageOutput = Projects.getBaseDirectory(project);
        dirBaseImageOutput = new File(dirBaseImageOutput, "TMA");
        dirBaseImageOutput = new File(dirBaseImageOutput, "images");
        if (!dirBaseImageOutput.exists())
            dirBaseImageOutput.mkdirs();
        Map<String, RunningStatistics> statsMap = new HashMap<>();
        for (ProjectImageEntry<BufferedImage> imageEntry : project.getImageList()) {
            // Look for data file
            if (!imageEntry.hasImageData())
                continue;
            File dirImageOutput = new File(dirBaseImageOutput, imageEntry.getImageName());
            if (!dirImageOutput.exists())
                dirImageOutput.mkdirs();
            // Read data
            ImageData<BufferedImage> imageData;
            try {
                imageData = imageEntry.readImageData();
            } catch (IOException e) {
                logger.error("Error reading ImageData for " + imageEntry.getImageName(), e);
                continue;
            }
            TMAGrid tmaGrid = imageData.getHierarchy().getTMAGrid();
            if (tmaGrid == null) {
                logger.warn("No TMA data for {}", imageEntry.getImageName());
                continue;
            }
            // Figure out downsample value
            ImageServer<BufferedImage> server = imageData.getServer();
            double downsample = Math.round(5 / server.getPixelCalibration().getAveragedPixelSizeMicrons());
            // Read the TMA entries
            int counter = 0;
            for (TMACoreObject core : tmaGrid.getTMACoreList()) {
                counter++;
                String name = core.getName();
                if (name == null)
                    name = Integer.toString(counter);
                File fileOutput = new File(dirImageOutput, name + ".jpg");
                if (!fileOutput.exists()) {
                    try {
                        RegionRequest request = RegionRequest.createInstance(server.getPath(), downsample, core.getROI());
                        BufferedImage img = server.readBufferedImage(request);
                        ImageIO.write(img, "jpg", fileOutput);
                    } catch (Exception e) {
                        logger.error("Unable to write {}", fileOutput.getAbsolutePath());
                    }
                }
                var entry = TMAEntries.createDefaultTMAEntry(imageEntry.getImageName(), fileOutput.getAbsolutePath(), null, core.getName(), core.isMissing());
                MeasurementList ml = core.getMeasurementList();
                for (int i = 0; i < ml.size(); i++) {
                    String measurement = ml.getMeasurementName(i);
                    double val = ml.getMeasurementValue(i);
                    entry.putMeasurement(measurement, val);
                    if (!Double.isNaN(val)) {
                        RunningStatistics stats = statsMap.get(measurement);
                        if (stats == null) {
                            stats = new RunningStatistics();
                            statsMap.put(measurement, stats);
                        }
                        stats.addValue(val);
                    }
                }
                entries.add(entry);
            }
            try {
                server.close();
            } catch (Exception e) {
                logger.warn("Problem closing server", e);
            }
        }
        // Loop through all entries and perform outlier count
        double k = 3;
        for (TMAEntry entry : entries) {
            int outlierCount = 0;
            for (Entry<String, RunningStatistics> statsEntry : statsMap.entrySet()) {
                RunningStatistics stats = statsEntry.getValue();
                double val = entry.getMeasurementAsDouble(statsEntry.getKey());
                if (!(val >= stats.getMean() - stats.getStdDev() * k && val <= stats.getMean() + stats.getStdDev() * k))
                    outlierCount++;
            }
            entry.putMeasurement("Outlier count", outlierCount);
        }
    }
    Stage stage = new Stage();
    stage.initOwner(qupath.getStage());
    TMASummaryViewer summaryViewer = new TMASummaryViewer(stage);
    summaryViewer.setTMAEntries(entries);
    summaryViewer.getStage().show();
}
Also used : HashMap(java.util.HashMap) TMACoreObject(qupath.lib.objects.TMACoreObject) MeasurementList(qupath.lib.measurements.MeasurementList) TMAEntry(qupath.lib.gui.tma.TMAEntries.TMAEntry) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) IOException(java.io.IOException) BufferedImage(java.awt.image.BufferedImage) IOException(java.io.IOException) RunningStatistics(qupath.lib.analysis.stats.RunningStatistics) Stage(javafx.stage.Stage) File(java.io.File) RegionRequest(qupath.lib.regions.RegionRequest)

Aggregations

MeasurementList (qupath.lib.measurements.MeasurementList)24 PathObject (qupath.lib.objects.PathObject)12 ArrayList (java.util.ArrayList)9 ROI (qupath.lib.roi.interfaces.ROI)9 BufferedImage (java.awt.image.BufferedImage)6 RegionRequest (qupath.lib.regions.RegionRequest)6 List (java.util.List)5 PixelCalibration (qupath.lib.images.servers.PixelCalibration)5 IOException (java.io.IOException)4 HashMap (java.util.HashMap)4 TMACoreObject (qupath.lib.objects.TMACoreObject)4 PathClass (qupath.lib.objects.classes.PathClass)4 LinkedHashSet (java.util.LinkedHashSet)3 Map (java.util.Map)3 SimpleModifiableImage (qupath.lib.analysis.images.SimpleModifiableImage)3 ImmutableDimension (qupath.lib.geom.ImmutableDimension)3 PathCellObject (qupath.lib.objects.PathCellObject)3 ParameterList (qupath.lib.plugins.parameters.ParameterList)3 Calibration (ij.measure.Calibration)2 ImageProcessor (ij.process.ImageProcessor)2