Search in sources :

Example 1 with SimpleModifiableImage

use of qupath.lib.analysis.images.SimpleModifiableImage 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 2 with SimpleModifiableImage

use of qupath.lib.analysis.images.SimpleModifiableImage in project qupath by qupath.

the class HaralickFeaturesPlugin method processObject.

static boolean processObject(final PathObject pathObject, final ParameterList params, final ImageServer<BufferedImage> server, final ColorDeconvolutionStains stains) throws IOException {
    String stainsName = (String) params.getChoiceParameterValue("stainChoice");
    double mag = params.getDoubleParameterValue("magnification");
    int d = params.getIntParameterValue("haralickDistance");
    int nBins = params.getIntParameterValue("haralickBins");
    boolean includeStats = params.getBooleanParameterValue("includeStats");
    boolean doCircular = params.getBooleanParameterValue("doCircular");
    double downsample;
    boolean hasMagnification = !Double.isNaN(server.getMetadata().getMagnification());
    PixelCalibration cal = server.getPixelCalibration();
    if (hasMagnification)
        downsample = server.getMetadata().getMagnification() / mag;
    else if (cal.hasPixelSizeMicrons()) {
        downsample = params.getDoubleParameterValue("pixelSizeMicrons") / cal.getAveragedPixelSizeMicrons();
    } else
        downsample = params.getDoubleParameterValue("downsample");
    // double downsample = server.getMagnification() / mag;
    // Try to get ROI
    ROI pathROI = null;
    if (pathObject instanceof PathCellObject && Boolean.TRUE.equals(params.getBooleanParameterValue("useNucleusROIs")))
        pathROI = ((PathCellObject) pathObject).getNucleusROI();
    else
        pathROI = pathObject.getROI();
    if (pathROI == null)
        return false;
    // Get bounds
    ImmutableDimension size = getPreferredTileSizePixels(server, params);
    RegionRequest region;
    boolean createMaskROI = false;
    if (size.getWidth() <= 0 || size.getHeight() <= 0) {
        region = RegionRequest.createInstance(server.getPath(), downsample, pathObject.getROI());
        createMaskROI = true;
        doCircular = false;
    } else if (size.getWidth() / downsample < 1 || size.getHeight() / downsample < 1)
        // Positive size, but insufficient to make measurements
        return false;
    else {
        // 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) ((int) (pathROI.getCentroidX() / downsample + .5) * downsample) - size.width / 2;
        int yStart = (int) ((int) (pathROI.getCentroidY() / downsample + .5) * 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 < 3 || region.getHeight() / downsample < 3)
        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 Haralick features for {}", pathObject);
        return false;
    }
    // Create mask ROI if necessary
    byte[] maskBytes = null;
    if (createMaskROI) {
        ROI roi = pathObject.getROI();
        // if (pathObject instanceof PathCellObject && ((PathCellObject)pathObject).getNucleusROI() != null)
        // roi = ((PathCellObject)pathObject).getNucleusROI();
        BufferedImage imgMask = BufferedImageTools.createROIMask(img.getWidth(), img.getHeight(), roi, region);
        maskBytes = ((DataBufferByte) imgMask.getRaster().getDataBuffer()).getData();
    }
    double minValue = Double.NaN;
    double maxValue = Double.NaN;
    // 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 = maskBytes == null ? " (" + getDiameterString(server, params) + ")" : "";
    if (stainsName.equals("H-DAB")) {
        minValue = 0;
        maxValue = 2.0;
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_DAB, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "DAB" + postfix, ColorTransformer.ColorTransformMethod.DAB_H_DAB, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("H&E")) {
        minValue = 0;
        maxValue = 2;
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_E, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Eosin" + postfix, ColorTransformer.ColorTransformMethod.Eosin_H_E, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("H-DAB (8-bit)")) {
        minValue = 0;
        maxValue = 255;
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin 8-bit" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_DAB_8_bit, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "DAB 8-bit" + postfix, ColorTransformer.ColorTransformMethod.DAB_H_DAB_8_bit, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("H&E (8-bit)")) {
        minValue = 0;
        maxValue = 255;
        processTransformedImage(pxImg, buf, pixels, measurementList, "Hematoxylin 8-bit" + postfix, ColorTransformer.ColorTransformMethod.Hematoxylin_H_E_8_bit, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Eosin 8-bit" + postfix, ColorTransformer.ColorTransformMethod.Eosin_H_E_8_bit, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("Optical density")) {
        minValue = 0;
        maxValue = 2.5;
        processTransformedImage(pxImg, buf, pixels, measurementList, "OD sum" + postfix, ColorTransformer.ColorTransformMethod.Optical_density_sum, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("RGB")) {
        minValue = 0;
        maxValue = 255;
        processTransformedImage(pxImg, buf, pixels, measurementList, "Red" + postfix, ColorTransformer.ColorTransformMethod.Red, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Green" + postfix, ColorTransformer.ColorTransformMethod.Green, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Blue" + postfix, ColorTransformer.ColorTransformMethod.Blue, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("RGB OD")) {
        minValue = 0;
        // Actual possible max is around 2.4 for 8-bit input... but this gives a lot of bins for (almost) saturated pixels
        maxValue = 1.5;
        processTransformedImage(pxImg, buf, pixels, measurementList, "Red OD" + postfix, ColorTransformer.ColorTransformMethod.Red_OD, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Green OD" + postfix, ColorTransformer.ColorTransformMethod.Green_OD, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(pxImg, buf, pixels, measurementList, "Blue OD" + postfix, ColorTransformer.ColorTransformMethod.Blue_OD, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("Grayscale")) {
        minValue = 0;
        maxValue = 255;
        processTransformedImage(pxImg, buf, pixels, measurementList, "Grayscale" + postfix, ColorTransformer.ColorTransformMethod.RGB_mean, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    } else if (stainsName.equals("HSB")) {
        minValue = 0;
        maxValue = 1;
        float[] hsb = null;
        double sinX = 0;
        double cosX = 0;
        float[] pixelsBrightness = new float[pixels.length];
        float[] pixelsSaturation = new float[pixels.length];
        for (int i = 0; i < buf.length; i++) {
            if (maskBytes != null && maskBytes[i] == (byte) 0)
                continue;
            int val = buf[i];
            hsb = Color.RGBtoHSB(ColorTools.red(val), ColorTools.green(val), ColorTools.blue(val), hsb);
            pixelsSaturation[i] = hsb[1];
            pixelsBrightness[i] = hsb[2];
            double alpha = hsb[0] * 2 * Math.PI;
            sinX += Math.sin(alpha);
            cosX += Math.cos(alpha);
        }
        measurementList.putMeasurement("Mean hue", Math.atan2(sinX, cosX) / (2 * Math.PI) + 0.5);
        // measurementList.putMeasurement("Mean saturation", hsb[1]);
        // measurementList.putMeasurement("Mean brightness", hsb[2]);
        processTransformedImage(SimpleImages.createFloatImage(pixelsSaturation, w, h), buf, pixelsSaturation, measurementList, "Saturation" + postfix, null, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
        processTransformedImage(SimpleImages.createFloatImage(pixelsBrightness, w, h), buf, pixelsBrightness, measurementList, "Brightness" + postfix, null, minValue, maxValue, d, nBins, stains, maskBytes, includeStats, doCircular);
    }
    measurementList.close();
    return true;
}
Also used : MeasurementList(qupath.lib.measurements.MeasurementList) PixelCalibration(qupath.lib.images.servers.PixelCalibration) ROI(qupath.lib.roi.interfaces.ROI) BufferedImage(java.awt.image.BufferedImage) SimpleModifiableImage(qupath.lib.analysis.images.SimpleModifiableImage) ImmutableDimension(qupath.lib.geom.ImmutableDimension) RegionRequest(qupath.lib.regions.RegionRequest) PathCellObject(qupath.lib.objects.PathCellObject)

Example 3 with SimpleModifiableImage

use of qupath.lib.analysis.images.SimpleModifiableImage in project qupath by qupath.

the class CoherenceFeaturePlugin 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");
    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());
    // Try to align with pixel boundaries according to the downsample being used - otherwise, interpolation can cause some strange, pattern artefacts
    int xStart = (int) ((int) (pathROI.getCentroidX() / downsample + .5) * downsample) - size.width / 2;
    int yStart = (int) ((int) (pathROI.getCentroidY() / downsample + .5) * downsample) - size.height / 2;
    int width = Math.min(server.getWidth(), xStart + size.width) - xStart;
    int height = Math.min(server.getHeight(), yStart + size.height) - yStart;
    RegionRequest region = RegionRequest.createInstance(server.getPath(), downsample, xStart, yStart, width, height, pathROI.getT(), pathROI.getZ());
    // System.out.println(bounds);
    // System.out.println("Size: " + size);
    BufferedImage img = server.readBufferedImage(region);
    // 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 4 with SimpleModifiableImage

use of qupath.lib.analysis.images.SimpleModifiableImage 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)

Aggregations

BufferedImage (java.awt.image.BufferedImage)4 SimpleModifiableImage (qupath.lib.analysis.images.SimpleModifiableImage)4 ImmutableDimension (qupath.lib.geom.ImmutableDimension)4 MeasurementList (qupath.lib.measurements.MeasurementList)4 RegionRequest (qupath.lib.regions.RegionRequest)4 ROI (qupath.lib.roi.interfaces.ROI)4 PixelCalibration (qupath.lib.images.servers.PixelCalibration)2 PathCellObject (qupath.lib.objects.PathCellObject)2 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 HaralickFeatureComputer (qupath.lib.analysis.features.HaralickFeatureComputer)1 PathAnnotationObject (qupath.lib.objects.PathAnnotationObject)1 TMACoreObject (qupath.lib.objects.TMACoreObject)1 ParameterList (qupath.lib.plugins.parameters.ParameterList)1