Search in sources :

Example 21 with TMACoreObject

use of qupath.lib.objects.TMACoreObject in project qupath by qupath.

the class QP method clearTMAGrid.

/**
 * Remove the TMA grid from the current {@code PathObjectHierarchy}.
 *
 * @see #getCurrentHierarchy
 */
public static void clearTMAGrid() {
    PathObjectHierarchy hierarchy = getCurrentHierarchy();
    if (hierarchy == null)
        return;
    hierarchy.setTMAGrid(null);
    PathObject selected = hierarchy.getSelectionModel().getSelectedObject();
    if (selected instanceof TMACoreObject)
        hierarchy.getSelectionModel().setSelectedObject(null);
}
Also used : PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathObject(qupath.lib.objects.PathObject) TMACoreObject(qupath.lib.objects.TMACoreObject)

Example 22 with TMACoreObject

use of qupath.lib.objects.TMACoreObject in project qupath by qupath.

the class SmoothFeaturesPlugin method getParentObjects.

@Override
protected Collection<PathObject> getParentObjects(final PluginRunner<T> runner) {
    PathObjectHierarchy hierarchy = runner.getImageData().getHierarchy();
    List<PathObject> parents = new ArrayList<>();
    if (hierarchy.getTMAGrid() != null) {
        logger.info("Smoothing using TMA cores");
        for (TMACoreObject core : hierarchy.getTMAGrid().getTMACoreList()) {
            if (core.hasChildren())
                parents.add(core);
        }
    } else {
        for (PathObject pathObject : hierarchy.getSelectionModel().getSelectedObjects()) {
            if (pathObject.isAnnotation() && pathObject.hasChildren())
                parents.add(pathObject);
        }
        if (!parents.isEmpty())
            logger.warn("Smoothing using annotations");
    }
    return parents;
}
Also used : PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathObject(qupath.lib.objects.PathObject) TMACoreObject(qupath.lib.objects.TMACoreObject) ArrayList(java.util.ArrayList)

Example 23 with TMACoreObject

use of qupath.lib.objects.TMACoreObject 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 TMACoreObject

use of qupath.lib.objects.TMACoreObject in project qupath by qupath.

the class MoveTool method mouseReleased.

@Override
public void mouseReleased(MouseEvent e) {
    super.mouseReleased(e);
    if (e.isConsumed())
        return;
    var viewer = getViewer();
    RoiEditor editor = viewer.getROIEditor();
    if (editor != null && (editor.hasActiveHandle() || editor.isTranslating())) {
        boolean roiChanged = (editor.isTranslating() && editor.finishTranslation()) || editor.hasActiveHandle();
        editor.resetActiveHandle();
        // if (editor.isTranslating())
        // editor.finishTranslation();
        e.consume();
        PathObject pathObject = viewer.getSelectedObject();
        if (requestParentClipping(e) && pathObject instanceof PathAnnotationObject) {
            ROI roiNew = refineROIByParent(pathObject.getROI());
            ((PathAnnotationObject) pathObject).setROI(roiNew);
        }
        if (pathObject != null && pathObject.hasROI() && pathObject.getROI().isEmpty()) {
            if (pathObject.getParent() != null)
                viewer.getHierarchy().removeObject(pathObject, true);
            viewer.setSelectedObject(null);
        } else {
            PathObjectHierarchy hierarchy = viewer.getHierarchy();
            if (pathObject instanceof TMACoreObject) {
                hierarchy.fireHierarchyChangedEvent(pathObject);
            } else if (pathObject != null) {
                // Handle ROI changes only if required
                if (roiChanged) {
                    var updatedROI = editor.getROI();
                    if (pathObject.getROI() != updatedROI && pathObject instanceof PathROIObject)
                        ((PathROIObject) pathObject).setROI(updatedROI);
                    // PathObject parentPrevious = pathObject.getParent();
                    hierarchy.removeObjectWithoutUpdate(pathObject, true);
                    if (getCurrentParent() == null || !PathPrefs.clipROIsForHierarchyProperty().get() || e.isShiftDown())
                        hierarchy.addPathObject(pathObject);
                    else
                        hierarchy.addPathObjectBelowParent(getCurrentParent(), pathObject, true);
                // PathObject parentNew = pathObject.getParent();
                // if (parentPrevious == parentNew)
                // hierarchy.fireHierarchyChangedEvent(this, parentPrevious);
                // else
                // hierarchy.fireHierarchyChangedEvent(this);
                }
            }
            viewer.setSelectedObject(pathObject);
        }
    }
    // Optionally continue a dragging movement until the canvas comes to a standstill
    if (pDragging != null && requestDynamicDragging && System.currentTimeMillis() - lastDragTimestamp < 100 && (dx * dx + dy * dy > viewer.getDownsampleFactor())) {
        mover = new ViewerMover(viewer);
        mover.startMoving(dx, dy, false);
    } else
        viewer.setDoFasterRepaint(false);
    // Make sure we don't have a previous point (to prevent weird dragging artefacts)
    pDragging = null;
// // If we were translating, stop
// if (editor.isTranslating()) {
// editor.finishTranslation();
// // TODO: Make this more efficient!
// viewer.getPathObjectHierarchy().fireHierarchyChangedEvent();
// return;
// }
}
Also used : PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) RoiEditor(qupath.lib.roi.RoiEditor) TMACoreObject(qupath.lib.objects.TMACoreObject) PathROIObject(qupath.lib.objects.PathROIObject) ROI(qupath.lib.roi.interfaces.ROI)

Example 25 with TMACoreObject

use of qupath.lib.objects.TMACoreObject in project qupath by qupath.

the class QP method clearSelectedObjects.

/**
 * Delete the selected objects from the current hierarchy, optionally keeping their child (descendant) objects.
 *
 * @param keepChildren
 */
public static void clearSelectedObjects(boolean keepChildren) {
    PathObjectHierarchy hierarchy = getCurrentHierarchy();
    if (hierarchy == null)
        return;
    Collection<PathObject> selectedRaw = hierarchy.getSelectionModel().getSelectedObjects();
    List<PathObject> selected = selectedRaw.stream().filter(p -> !(p instanceof TMACoreObject)).collect(Collectors.toList());
    hierarchy.removeObjects(selected, keepChildren);
    hierarchy.getSelectionModel().clearSelection();
}
Also used : FeatureExtractors(qupath.opencv.ml.objects.features.FeatureExtractors) Arrays(java.util.Arrays) ServerTools(qupath.lib.images.servers.ServerTools) PathTileObject(qupath.lib.objects.PathTileObject) IJTools(qupath.imagej.tools.IJTools) GroovyCV(qupath.opencv.tools.GroovyCV) CommandLinePluginRunner(qupath.lib.plugins.CommandLinePluginRunner) ImageRegion(qupath.lib.regions.ImageRegion) Map(java.util.Map) PixelClassifierTools(qupath.opencv.ml.pixel.PixelClassifierTools) Path(java.nio.file.Path) ColorTools(qupath.lib.common.ColorTools) Member(java.lang.reflect.Member) PathObjects(qupath.lib.objects.PathObjects) Set(java.util.Set) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Project(qupath.lib.projects.Project) Stream(java.util.stream.Stream) ColorModels(qupath.lib.analysis.heatmaps.ColorModels) ShapeFeatures(qupath.lib.analysis.features.ObjectMeasurements.ShapeFeatures) DensityMaps(qupath.lib.analysis.heatmaps.DensityMaps) PathObjectPredicates(qupath.lib.objects.PathObjectPredicates) GeoJsonExportOptions(qupath.lib.io.PathIO.GeoJsonExportOptions) GsonTools(qupath.lib.io.GsonTools) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Constructor(java.lang.reflect.Constructor) PathPlugin(qupath.lib.plugins.PathPlugin) Projects(qupath.lib.projects.Projects) ArrayList(java.util.ArrayList) ROIs(qupath.lib.roi.ROIs) ImageOps(qupath.opencv.ops.ImageOps) LinkedHashSet(java.util.LinkedHashSet) PathClassifierTools(qupath.lib.classifiers.PathClassifierTools) ObjectArrays(com.google.common.collect.ObjectArrays) Files(java.nio.file.Files) GeneralTools(qupath.lib.common.GeneralTools) RegionRequest(qupath.lib.regions.RegionRequest) TileExporter(qupath.lib.images.writers.TileExporter) DistanceTools(qupath.lib.analysis.DistanceTools) IOException(java.io.IOException) Padding(qupath.lib.regions.Padding) Field(java.lang.reflect.Field) DelaunayTools(qupath.lib.analysis.DelaunayTools) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) ROI(qupath.lib.roi.interfaces.ROI) PixelClassifier(qupath.lib.classifiers.pixel.PixelClassifier) Paths(java.nio.file.Paths) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) UriResource(qupath.lib.io.UriResource) ImageServerMetadata(qupath.lib.images.servers.ImageServerMetadata) PathIO(qupath.lib.io.PathIO) RunSavedClassifierWorkflowStep(qupath.lib.plugins.workflow.RunSavedClassifierWorkflowStep) CreateObjectOptions(qupath.opencv.ml.pixel.PixelClassifierTools.CreateObjectOptions) ImageServer(qupath.lib.images.servers.ImageServer) OpenCVTypeAdapters(qupath.opencv.io.OpenCVTypeAdapters) LoggerFactory(org.slf4j.LoggerFactory) Scanner(java.util.Scanner) PathObjectFilter(qupath.lib.objects.PathObjectFilter) OpenCVMLClassifier(qupath.opencv.ml.objects.OpenCVMLClassifier) BufferedImageTools(qupath.lib.awt.common.BufferedImageTools) URI(java.net.URI) ImageServers(qupath.lib.images.servers.ImageServers) Method(java.lang.reflect.Method) ImageType(qupath.lib.images.ImageData.ImageType) ObjectMeasurements(qupath.lib.analysis.features.ObjectMeasurements) BufferedImage(java.awt.image.BufferedImage) PixelClassifiers(qupath.opencv.ml.pixel.PixelClassifiers) Predicate(java.util.function.Predicate) ImageServerProvider(qupath.lib.images.servers.ImageServerProvider) Collection(java.util.Collection) DensityMapBuilder(qupath.lib.analysis.heatmaps.DensityMaps.DensityMapBuilder) UriUpdater(qupath.lib.io.UriUpdater) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) PathObject(qupath.lib.objects.PathObject) PathDetectionObject(qupath.lib.objects.PathDetectionObject) List(java.util.List) ProjectIO(qupath.lib.projects.ProjectIO) ContourTracing(qupath.lib.analysis.images.ContourTracing) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) Modifier(java.lang.reflect.Modifier) DnnTools(qupath.opencv.dnn.DnnTools) ImagePlane(qupath.lib.regions.ImagePlane) Geometry(org.locationtech.jts.geom.Geometry) Pattern(java.util.regex.Pattern) PathCellObject(qupath.lib.objects.PathCellObject) PathClassTools(qupath.lib.objects.classes.PathClassTools) ImageChannel(qupath.lib.images.servers.ImageChannel) OpenCVTools(qupath.opencv.tools.OpenCVTools) HashMap(java.util.HashMap) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) ColorTransforms(qupath.lib.images.servers.ColorTransforms) CellTools(qupath.lib.objects.CellTools) HashSet(java.util.HashSet) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains) ObjectClassifiers(qupath.lib.classifiers.object.ObjectClassifiers) GeometryTools(qupath.lib.roi.GeometryTools) NoSuchElementException(java.util.NoSuchElementException) WeakHashMap(java.util.WeakHashMap) ImageData(qupath.lib.images.ImageData) RoiTools(qupath.lib.roi.RoiTools) Logger(org.slf4j.Logger) ProjectImageEntry(qupath.lib.projects.ProjectImageEntry) ImageWriterTools(qupath.lib.images.writers.ImageWriterTools) PixelType(qupath.lib.images.servers.PixelType) PathClass(qupath.lib.objects.classes.PathClass) PointIO(qupath.lib.io.PointIO) TMACoreObject(qupath.lib.objects.TMACoreObject) ObjectClassifier(qupath.lib.classifiers.object.ObjectClassifier) Comparator(java.util.Comparator) Collections(java.util.Collections) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathObject(qupath.lib.objects.PathObject) TMACoreObject(qupath.lib.objects.TMACoreObject)

Aggregations

TMACoreObject (qupath.lib.objects.TMACoreObject)35 PathObject (qupath.lib.objects.PathObject)20 ArrayList (java.util.ArrayList)17 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)15 TMAGrid (qupath.lib.objects.hierarchy.TMAGrid)13 BufferedImage (java.awt.image.BufferedImage)12 PathAnnotationObject (qupath.lib.objects.PathAnnotationObject)12 ROI (qupath.lib.roi.interfaces.ROI)11 IOException (java.io.IOException)9 List (java.util.List)9 RegionRequest (qupath.lib.regions.RegionRequest)9 File (java.io.File)6 ImageServer (qupath.lib.images.servers.ImageServer)6 PathDetectionObject (qupath.lib.objects.PathDetectionObject)6 Collection (java.util.Collection)5 Collectors (java.util.stream.Collectors)5 HashSet (java.util.HashSet)4 LinkedHashMap (java.util.LinkedHashMap)4 Insets (javafx.geometry.Insets)4 Scene (javafx.scene.Scene)4