Search in sources :

Example 91 with PathObject

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

the class ClassifierBuilderPane method selectAllFeatures.

/**
 * Try to select all features, forcing an update to check for current objects
 */
private void selectAllFeatures() {
    Map<PathClass, List<PathObject>> map = getTrainingMap();
    Set<String> featureNames = new TreeSet<>();
    for (List<PathObject> list : map.values()) {
        for (PathObject temp : list) {
            featureNames.addAll(temp.getMeasurementList().getMeasurementNames());
        }
    }
    // If we don't have any training features, let feature panel try to get them itself for current ImageDat
    if (featureNames.isEmpty())
        featurePanel.ensureMeasurementsUpdated();
    else
        featurePanel.updateMeasurementsByNames(featureNames);
    featurePanel.selectAllAvailableFeatures();
    updateSelectedFeaturesLabel();
}
Also used : PathClass(qupath.lib.objects.classes.PathClass) PathObject(qupath.lib.objects.PathObject) TreeSet(java.util.TreeSet) ParameterList(qupath.lib.plugins.parameters.ParameterList) List(java.util.List) ArrayList(java.util.ArrayList)

Example 92 with PathObject

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

the class PathClassificationLabellingHelper method getClassificationMap.

/**
 * Get a map of training data, based on the child objects of some classified annotations.
 *
 * @param hierarchy the hierarchy containing all the objects and annotations.
 * @param pointsOnly if true, only Point annotations will be used for training.
 *
 * @return
 */
public static Map<PathClass, List<PathObject>> getClassificationMap(final PathObjectHierarchy hierarchy, final boolean pointsOnly) {
    Map<PathClass, List<PathObject>> classifications = new TreeMap<>();
    // Get the annotations & filter out those that are useful
    List<PathObject> annotations = new ArrayList<>(getAnnotations(hierarchy));
    Iterator<PathObject> iter = annotations.iterator();
    while (iter.hasNext()) {
        PathObject pathObject = iter.next();
        // We need a PathClass, and may need to only include points
        if (pathObject.getPathClass() == null || pathObject.getPathClass() == PathClassFactory.getPathClass(StandardPathClasses.REGION) || (pointsOnly && !PathObjectTools.hasPointROI(pathObject)))
            iter.remove();
        else
            classifications.put(pathObject.getPathClass(), new ArrayList<>());
    }
    // from the hierarchy
    if (annotations.size() > 1) {
        annotations.sort(new Comparator<PathObject>() {

            @Override
            public int compare(PathObject o1, PathObject o2) {
                PathAnnotationObject p1 = (PathAnnotationObject) o1;
                PathAnnotationObject p2 = (PathAnnotationObject) o2;
                int comp = 0;
                if (p1.hasROI()) {
                    if (p2.hasROI()) {
                        comp = Double.compare(p1.getROI().getCentroidY(), p2.getROI().getCentroidY());
                        if (comp == 0)
                            comp = Double.compare(p1.getROI().getCentroidX(), p2.getROI().getCentroidX());
                        if (comp == 0)
                            comp = p1.getROI().toString().compareTo(p2.getROI().toString());
                    }
                }
                if (comp == 0)
                    return Integer.compare(o1.hashCode(), o2.hashCode());
                else
                    return comp;
            }
        });
    }
    // StringBuilder sb = new StringBuilder("DETECTIONS:\t");
    for (PathObject pathObject : annotations) {
        PathClass pathClass = pathObject.getPathClass();
        List<PathObject> list = classifications.get(pathClass);
        // sb.append(list.size() + ", ");
        if (PathObjectTools.hasPointROI(pathObject)) {
            for (Point2 p : ((PointsROI) pathObject.getROI()).getAllPoints()) {
                // TODO: Pay attention to z & t position!
                Collection<PathObject> pathObjectsTemp = PathObjectTools.getObjectsForLocation(hierarchy, p.getX(), p.getY(), 0, 0, -1);
                pathObjectsTemp = PathObjectTools.getObjectsOfClass(pathObjectsTemp, PathDetectionObject.class);
                // Clumsy way to avoid duplicates...
                list.removeAll(pathObjectsTemp);
                list.addAll(pathObjectsTemp);
            }
        } else
            list.addAll(hierarchy.getObjectsForROI(PathDetectionObject.class, pathObject.getROI()));
    }
    for (Entry<PathClass, List<PathObject>> entry : classifications.entrySet()) {
        logger.info(entry.getKey() + ": " + entry.getValue().size());
    }
    return classifications;
}
Also used : PathDetectionObject(qupath.lib.objects.PathDetectionObject) ArrayList(java.util.ArrayList) PointsROI(qupath.lib.roi.PointsROI) TreeMap(java.util.TreeMap) PathClass(qupath.lib.objects.classes.PathClass) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) Point2(qupath.lib.geom.Point2) ArrayList(java.util.ArrayList) List(java.util.List)

Example 93 with PathObject

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

the class PathClassificationLabellingHelper method resampleClassificationMap.

/**
 * Resample a training map (PathClass label &amp; lists of PathObjects that should have the specified classifications) so that
 * it contains only a specified proportion of entries.
 *
 * @param map
 * @param splitType
 * @param proportion between 0 (empty map) and 1
 * @param seed
 * @return
 */
public static Map<PathClass, List<PathObject>> resampleClassificationMap(final Map<PathClass, List<PathObject>> map, final SplitType splitType, final double proportion, final long seed) {
    if (proportion > 1 || proportion == 0)
        throw new IllegalArgumentException("Proportion of samples to use for training cannot be < 0 or > 1!");
    if (proportion == 0)
        return Collections.emptyMap();
    if (proportion == 1 && splitType != SplitType.RANDOM_WITH_REPLACEMENT)
        return map;
    int n = 0;
    for (List<PathObject> temp : map.values()) n += temp.size();
    int maxTrainingInstances = (int) (n * proportion + .5);
    List<TrainingEntry> entries = new ArrayList<>();
    for (Entry<PathClass, List<PathObject>> entry : map.entrySet()) {
        List<PathObject> list = entry.getValue();
        if (splitType == SplitType.LAST_SAMPLES)
            Collections.reverse(list);
        int maxCount = Integer.MAX_VALUE;
        if (splitType == SplitType.LAST_SAMPLES || splitType == SplitType.FIRST_SAMPLES)
            maxCount = (int) (list.size() * proportion + .9);
        PathClass pathClass = entry.getKey();
        int count = 0;
        for (PathObject temp : list) {
            entries.add(new TrainingEntry(pathClass, temp));
            count++;
            if (count >= maxCount)
                break;
        }
    }
    Map<PathClass, List<PathObject>> map2 = new TreeMap<>();
    Random random = new Random(seed);
    switch(splitType) {
        case EQUIDISTANT:
            double increment = 1.0 / proportion;
            for (double i = 0; i < entries.size(); i += increment) {
                int ind = (int) i;
                TrainingEntry entry = entries.get(ind);
                addToMap(map2, entry.pathClass, entry.pathObject);
            }
            ;
            return map2;
        // return resampleClassificationMapEquidistantly(map, proportion);
        case RANDOM_NO_REPLACEMENT:
            Collections.shuffle(entries, random);
        // Fall through...
        case FIRST_SAMPLES:
        // Fall through...
        case LAST_SAMPLES:
            for (int i = 0; i < maxTrainingInstances; i++) {
                TrainingEntry entry = entries.get(i);
                addToMap(map2, entry.pathClass, entry.pathObject);
            }
            ;
            return map2;
        case RANDOM_WITH_REPLACEMENT:
            for (int i = 0; i < maxTrainingInstances; i++) {
                int ind = random.nextInt(n);
                TrainingEntry entry = entries.get(ind);
                addToMap(map2, entry.pathClass, entry.pathObject);
            }
            ;
            return map2;
        default:
            break;
    }
    return map;
}
Also used : ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) PathClass(qupath.lib.objects.classes.PathClass) PathObject(qupath.lib.objects.PathObject) Random(java.util.Random) ArrayList(java.util.ArrayList) List(java.util.List)

Example 94 with PathObject

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

the class PathClassifierPane method runClassifier.

void runClassifier() {
    QuPathViewer viewer = viewerValue.getValue();
    if (viewer == null)
        return;
    ImageData<BufferedImage> imageData = viewer.getImageData();
    if (classifier == null || imageData == null || !classifier.isValid())
        return;
    Collection<PathObject> pathObjects = imageData.getHierarchy().getDetectionObjects();
    var availableFeatures = PathClassifierTools.getAvailableFeatures(pathObjects);
    var requiredFeatures = classifier.getRequiredMeasurements();
    String missingFeatures = requiredFeatures.stream().filter(p -> !availableFeatures.contains(p)).collect(Collectors.joining("\n\t"));
    if (!missingFeatures.isEmpty())
        logger.warn("Detection objects are missing the following feature(s):\n\t" + missingFeatures + "\nWill proceed with classification anyway..");
    // SwingUtilities.getRoot(viewer).setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    try {
        PathClassifierTools.runClassifier(imageData.getHierarchy(), classifier);
        // Log the classifier
        if (pathClassifier != null) {
            imageData.getHistoryWorkflow().addStep(new RunSavedClassifierWorkflowStep(pathClassifier));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // SwingUtilities.getRoot(viewer).setCursor(cursor);
        // Update displayed list - names may have changed - and classifier summary
        updateClassifierSummary();
    }
}
Also used : Button(javafx.scene.control.Button) ImageData(qupath.lib.images.ImageData) RunSavedClassifierWorkflowStep(qupath.lib.plugins.workflow.RunSavedClassifierWorkflowStep) PathClassifierTools(qupath.lib.classifiers.PathClassifierTools) Logger(org.slf4j.Logger) TextArea(javafx.scene.control.TextArea) BufferedImage(java.awt.image.BufferedImage) Date(java.util.Date) Collection(java.util.Collection) LoggerFactory(org.slf4j.LoggerFactory) SimpleDateFormat(java.text.SimpleDateFormat) Collectors(java.util.stream.Collectors) File(java.io.File) PathObject(qupath.lib.objects.PathObject) Dialogs(qupath.lib.gui.dialogs.Dialogs) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) ObservableValue(javafx.beans.value.ObservableValue) BorderPane(javafx.scene.layout.BorderPane) GridPane(javafx.scene.layout.GridPane) Pane(javafx.scene.layout.Pane) PaneTools(qupath.lib.gui.tools.PaneTools) PathObject(qupath.lib.objects.PathObject) RunSavedClassifierWorkflowStep(qupath.lib.plugins.workflow.RunSavedClassifierWorkflowStep) BufferedImage(java.awt.image.BufferedImage) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer)

Example 95 with PathObject

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

the class RetainedTrainingObjects method addToTrainingMap.

/**
 * Append retained objects, grouped by classification, to an existing training map.
 *
 * @param map
 * @return
 */
public int addToTrainingMap(final Map<PathClass, List<PathObject>> map) {
    int retainedImageCount = 0;
    for (Entry<String, Map<PathClass, List<PathObject>>> entry : retainedObjectsMap.entrySet()) {
        // Put any retained objects into the map
        Map<PathClass, List<PathObject>> map2 = entry.getValue();
        for (Entry<PathClass, List<PathObject>> entry2 : map2.entrySet()) {
            PathClass pathClassTemp = entry2.getKey();
            List<PathObject> listMain = map.get(pathClassTemp);
            if (listMain == null) {
                listMain = new ArrayList<>();
                map.put(pathClassTemp, listMain);
            }
            listMain.addAll(entry2.getValue());
        }
        retainedImageCount++;
    }
    return retainedImageCount;
}
Also used : PathClass(qupath.lib.objects.classes.PathClass) PathObject(qupath.lib.objects.PathObject) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) Map(java.util.Map)

Aggregations

PathObject (qupath.lib.objects.PathObject)182 ArrayList (java.util.ArrayList)84 ROI (qupath.lib.roi.interfaces.ROI)74 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)61 List (java.util.List)48 BufferedImage (java.awt.image.BufferedImage)37 IOException (java.io.IOException)37 PathClass (qupath.lib.objects.classes.PathClass)37 Collectors (java.util.stream.Collectors)35 PathAnnotationObject (qupath.lib.objects.PathAnnotationObject)34 Map (java.util.Map)33 Logger (org.slf4j.Logger)33 LoggerFactory (org.slf4j.LoggerFactory)33 ImageData (qupath.lib.images.ImageData)31 TMACoreObject (qupath.lib.objects.TMACoreObject)31 Collection (java.util.Collection)29 Collections (java.util.Collections)29 HashMap (java.util.HashMap)28 PathObjectTools (qupath.lib.objects.PathObjectTools)26 Arrays (java.util.Arrays)25