Search in sources :

Example 1 with PathObjectClassifier

use of qupath.lib.classifiers.PathObjectClassifier in project qupath by qupath.

the class PathIntensityClassifierPane method getIntensityClassifier.

/**
 * Returns a PathIntensityClassifier, or null if none was requested by the user's interactions with this JPanel.
 * @return
 */
public PathObjectClassifier getIntensityClassifier() {
    String intensityMeasurement = comboIntensities.getSelectionModel().getSelectedItem();
    PathObjectClassifier intensityClassifier = null;
    if (intensityMeasurement != null && !intensityMeasurement.equals("None")) {
        boolean singleThreshold = paramsIntensity.getBooleanParameterValue("single_threshold");
        double t1 = paramsIntensity.getDoubleParameterValue("threshold_1");
        // PathClass baseClass = PathClassFactory.getDefaultPathClass(PathClassFactory.PathClasses.TUMOR);
        PathClass baseClass = null;
        if (singleThreshold) {
            intensityClassifier = PathClassifierTools.createIntensityClassifier(baseClass, intensityMeasurement, t1);
        } else {
            double t2 = Math.max(t1, paramsIntensity.getDoubleParameterValue("threshold_2"));
            double t3 = Math.max(t2, paramsIntensity.getDoubleParameterValue("threshold_3"));
            intensityClassifier = PathClassifierTools.createIntensityClassifier(baseClass, intensityMeasurement, t1, t2, t3);
        }
    }
    return intensityClassifier;
}
Also used : PathClass(qupath.lib.objects.classes.PathClass) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier)

Example 2 with PathObjectClassifier

use of qupath.lib.classifiers.PathObjectClassifier in project qupath by qupath.

the class ClassifierBuilderPane method crossValidateAcrossImages.

private void crossValidateAcrossImages() {
    // Try to put the current image data information into the tempMap, which stores training data separated by image path
    updateRetainedObjectsMap();
    Map<String, Map<PathClass, List<PathObject>>> tempMap = new LinkedHashMap<>(retainedObjectsMap.getMap());
    Normalization normalization = (Normalization) paramsUpdate.getChoiceParameterValue("normalizationMethod");
    for (String key : tempMap.keySet()) {
        Map<PathClass, List<PathObject>> validationMap = tempMap.get(key);
        Map<PathClass, List<PathObject>> trainingMap = new LinkedHashMap<>();
        for (Entry<String, Map<PathClass, List<PathObject>>> entry : tempMap.entrySet()) {
            if (entry.getKey().equals(key))
                continue;
            for (Entry<PathClass, List<PathObject>> entry2 : entry.getValue().entrySet()) {
                if (trainingMap.containsKey(entry2.getKey())) {
                    trainingMap.get(entry2.getKey()).addAll(entry2.getValue());
                } else {
                    trainingMap.put(entry2.getKey(), new ArrayList<>(entry2.getValue()));
                }
            }
        }
        // Perform subsampling
        SplitType splitType = (SplitType) paramsUpdate.getChoiceParameterValue("splitType");
        double maxTrainingProportion = paramsUpdate.getIntParameterValue("maxTrainingPercent") / 100.;
        long seed = paramsUpdate.getIntParameterValue("randomSeed");
        trainingMap = PathClassificationLabellingHelper.resampleClassificationMap(trainingMap, splitType, maxTrainingProportion, seed);
        // Get the current classifier - unfortunately, there's no easy way to duplicate/create a new one,
        // so we are left working with the 'live' classifier
        PathObjectClassifier classifier = (T) comboClassifiers.getSelectionModel().getSelectedItem();
        classifier.updateClassifier(trainingMap, featurePanel.getSelectedFeatures(), normalization);
        int nCorrect = 0;
        int nTested = 0;
        for (Entry<PathClass, List<PathObject>> entryValidation : validationMap.entrySet()) {
            classifier.classifyPathObjects(entryValidation.getValue());
            for (PathObject temp : entryValidation.getValue()) {
                if (entryValidation.getKey().equals(temp.getPathClass()))
                    nCorrect++;
                nTested++;
            }
        }
        double percent = nCorrect * 100.0 / nTested;
        logger.info(String.format("Percentage correct for %s: %.2f%%", key, percent));
        System.err.println(String.format("Percentage correct for %s: %.2f%% (%d/%d)", key, percent, nCorrect, nTested));
    }
    // Force a normal classifier update, to compensate for the fact we had to modify the 'live' classifier
    updateClassification(false);
}
Also used : PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) LinkedHashMap(java.util.LinkedHashMap) PathClass(qupath.lib.objects.classes.PathClass) PathObject(qupath.lib.objects.PathObject) SplitType(qupath.process.gui.ml.legacy.PathClassificationLabellingHelper.SplitType) Normalization(qupath.lib.classifiers.Normalization) ParameterList(qupath.lib.plugins.parameters.ParameterList) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Example 3 with PathObjectClassifier

use of qupath.lib.classifiers.PathObjectClassifier in project qupath by qupath.

the class ClassifierBuilderPane method updateIntensityPanelCallback.

private void updateIntensityPanelCallback() {
    PathObjectHierarchy hierarchy = getHierarchy();
    PathObjectClassifier intensityClassifier = panelIntensities.getIntensityClassifier();
    if (intensityClassifier == null || hierarchy == null || classifier == null || !classifier.isValid() || !tbAutoUpdate.isSelected() || updatingClassification)
        return;
    // We may need to do a bigger reclassification
    if (hierarchyChanged)
        maybeUpdate();
    else {
        Collection<PathObject> pathObjects = hierarchy.getDetectionObjects();
        if (intensityClassifier.classifyPathObjects(pathObjects) > 0) {
            // Update displayed list - names may have changed - and classifier summary
            updateClassifierSummary(null);
            hierarchy.fireObjectClassificationsChangedEvent(this, pathObjects);
        }
    }
}
Also used : PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) PathObject(qupath.lib.objects.PathObject)

Example 4 with PathObjectClassifier

use of qupath.lib.classifiers.PathObjectClassifier in project qupath by qupath.

the class ClassifierBuilderPane method doClassification.

private void doClassification(final PathObjectHierarchy hierarchy, final List<String> features, final Map<PathClass, List<PathObject>> mapTraining, final Map<PathClass, List<PathObject>> mapTest, final boolean testOnTrainingData) {
    if (!Platform.isFxApplicationThread())
        Platform.runLater(() -> {
            progressIndicator.setProgress(-1);
            progressIndicator.setPrefSize(30, 30);
            progressIndicator.setVisible(true);
        });
    long startTime = System.currentTimeMillis();
    // Train classifier with requested normalization
    Normalization normalization = (Normalization) paramsUpdate.getChoiceParameterValue("normalizationMethod");
    String errorMessage = null;
    boolean classifierChanged = classifier != lastClassifierCompleted;
    try {
        classifierChanged = classifier.updateClassifier(mapTraining, features, normalization) || classifierChanged;
    } catch (Exception e) {
        errorMessage = "Classifier training failed with message:\n" + e.getLocalizedMessage() + "\nPlease try again with different settings.";
        e.printStackTrace();
    }
    if (classifier == null || !classifier.isValid()) {
        updateClassifierSummary(errorMessage);
        logger.error("Classifier is invalid!");
        updatingClassification = false;
        btnSaveClassifier.setDisable(classifier == null || !classifier.isValid());
        return;
    }
    long middleTime = System.currentTimeMillis();
    logger.info(String.format("Classifier training time: %.2f seconds", (middleTime - startTime) / 1000.));
    // Create an intensity classifier, if required
    PathObjectClassifier intensityClassifier = panelIntensities.getIntensityClassifier();
    // Apply classifier to everything
    Collection<PathObject> pathObjectsOrig = hierarchy.getDetectionObjects();
    int nClassified = 0;
    // Possible get proxy objects, depending on the thread we're on
    Collection<PathObject> pathObjects;
    if (Platform.isFxApplicationThread())
        pathObjects = pathObjectsOrig;
    else
        pathObjects = pathObjectsOrig.stream().map(p -> new PathObjectClassificationProxy(p)).collect(Collectors.toList());
    // Omit any objects that have already been classified by anything other than any of the target classes
    if (paramsUpdate.getBooleanParameterValue("limitTrainingToRepresentedClasses")) {
        Iterator<PathObject> iterator = pathObjects.iterator();
        Set<PathClass> representedClasses = mapTraining.keySet();
        while (iterator.hasNext()) {
            PathClass currentClass = iterator.next().getPathClass();
            if (currentClass != null && !representedClasses.contains(currentClass.getBaseClass()))
                iterator.remove();
        }
    }
    // In the event that we're using retained images, ensure we classify everything in our test set
    if (retainedObjectsMap.size() > 1 && !mapTest.isEmpty()) {
        for (Entry<PathClass, List<PathObject>> entry : mapTest.entrySet()) {
            pathObjects.addAll(entry.getValue());
        }
    }
    if (classifierChanged || hierarchyChanged) {
        nClassified = classifier.classifyPathObjects(pathObjects);
    } else {
        logger.info("Main classifier unchanged...");
    }
    if (intensityClassifier != null)
        intensityClassifier.classifyPathObjects(pathObjects);
    // }
    if (nClassified > 0) {
    // qupath.getViewer().repaint();
    } else if (classifierChanged || hierarchyChanged)
        logger.error("Classification failed - no objects classified!");
    long endTime = System.currentTimeMillis();
    logger.info(String.format("Classification time: %.2f seconds", (endTime - middleTime) / 1000.));
    // panelClassifier.setCursor(cursor);
    completeClassification(hierarchy, pathObjects, pathObjectsOrig, mapTest, testOnTrainingData);
}
Also used : Button(javafx.scene.control.Button) RunSavedClassifierWorkflowStep(qupath.lib.plugins.workflow.RunSavedClassifierWorkflowStep) Arrays(java.util.Arrays) BufferedInputStream(java.io.BufferedInputStream) ListCell(javafx.scene.control.ListCell) HierarchyEventType(qupath.lib.objects.hierarchy.events.PathObjectHierarchyEvent.HierarchyEventType) ObjectInputStream(java.io.ObjectInputStream) LoggerFactory(org.slf4j.LoggerFactory) Random(java.util.Random) VBox(javafx.scene.layout.VBox) Task(javafx.concurrent.Task) ParameterList(qupath.lib.plugins.parameters.ParameterList) ReadOnlyObjectWrapper(javafx.beans.property.ReadOnlyObjectWrapper) ComboBox(javafx.scene.control.ComboBox) ContextMenu(javafx.scene.control.ContextMenu) PathObjectHierarchyEvent(qupath.lib.objects.hierarchy.events.PathObjectHierarchyEvent) Map(java.util.Map) StandardPathClasses(qupath.lib.objects.classes.PathClassFactory.StandardPathClasses) Parameterizable(qupath.lib.plugins.parameters.Parameterizable) TableView(javafx.scene.control.TableView) QuPathGUI(qupath.lib.gui.QuPathGUI) Pane(javafx.scene.layout.Pane) PrintWriter(java.io.PrintWriter) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) Collection(java.util.Collection) Set(java.util.Set) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) Platform(javafx.application.Platform) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) Priority(javafx.scene.layout.Priority) List(java.util.List) Project(qupath.lib.projects.Project) ToggleButton(javafx.scene.control.ToggleButton) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) Entry(java.util.Map.Entry) BorderPane(javafx.scene.layout.BorderPane) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) TextArea(javafx.scene.control.TextArea) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) TreeSet(java.util.TreeSet) BufferedOutputStream(java.io.BufferedOutputStream) ArrayList(java.util.ArrayList) TableColumn(javafx.scene.control.TableColumn) LinkedHashMap(java.util.LinkedHashMap) Dialogs(qupath.lib.gui.dialogs.Dialogs) Insets(javafx.geometry.Insets) ProgressBar(javafx.scene.control.ProgressBar) Normalization(qupath.lib.classifiers.Normalization) ObjectOutputStream(java.io.ObjectOutputStream) SplitType(qupath.process.gui.ml.legacy.PathClassificationLabellingHelper.SplitType) Callback(javafx.util.Callback) Tooltip(javafx.scene.control.Tooltip) GridPane(javafx.scene.layout.GridPane) ImageData(qupath.lib.images.ImageData) ProgressIndicator(javafx.scene.control.ProgressIndicator) PathClassifierTools(qupath.lib.classifiers.PathClassifierTools) Modality(javafx.stage.Modality) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) TitledPane(javafx.scene.control.TitledPane) Iterator(java.util.Iterator) ProjectImageEntry(qupath.lib.projects.ProjectImageEntry) PathClass(qupath.lib.objects.classes.PathClass) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) Cursor(javafx.scene.Cursor) ROI(qupath.lib.roi.interfaces.ROI) SelectionMode(javafx.scene.control.SelectionMode) TreeMap(java.util.TreeMap) Stage(javafx.stage.Stage) ParameterPanelFX(qupath.lib.gui.dialogs.ParameterPanelFX) ObservableValue(javafx.beans.value.ObservableValue) PathObjectHierarchyListener(qupath.lib.objects.hierarchy.events.PathObjectHierarchyListener) ChangeListener(javafx.beans.value.ChangeListener) Collections(java.util.Collections) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) PathClass(qupath.lib.objects.classes.PathClass) PathObject(qupath.lib.objects.PathObject) Normalization(qupath.lib.classifiers.Normalization) ParameterList(qupath.lib.plugins.parameters.ParameterList) List(java.util.List) ArrayList(java.util.ArrayList)

Example 5 with PathObjectClassifier

use of qupath.lib.classifiers.PathObjectClassifier in project qupath by qupath.

the class QP method runClassifier.

/**
 * Run a detection object classifier for the current image data, reading the classifier from a specified path
 * @param path
 */
@Deprecated
public static void runClassifier(final String path) {
    ImageData<?> imageData = getCurrentImageData();
    if (imageData == null)
        return;
    PathObjectClassifier classifier = PathClassifierTools.loadClassifier(new File(path));
    if (classifier == null) {
        logger.error("Could not load classifier from {}", path);
        return;
    }
    runClassifier(imageData, classifier);
    // Log the step
    imageData.getHistoryWorkflow().addStep(new RunSavedClassifierWorkflowStep(path));
}
Also used : PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) RunSavedClassifierWorkflowStep(qupath.lib.plugins.workflow.RunSavedClassifierWorkflowStep) File(java.io.File)

Aggregations

PathObjectClassifier (qupath.lib.classifiers.PathObjectClassifier)5 PathObject (qupath.lib.objects.PathObject)3 PathClass (qupath.lib.objects.classes.PathClass)3 File (java.io.File)2 ArrayList (java.util.ArrayList)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 Map (java.util.Map)2 TreeMap (java.util.TreeMap)2 Normalization (qupath.lib.classifiers.Normalization)2 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)2 ParameterList (qupath.lib.plugins.parameters.ParameterList)2 RunSavedClassifierWorkflowStep (qupath.lib.plugins.workflow.RunSavedClassifierWorkflowStep)2 SplitType (qupath.process.gui.ml.legacy.PathClassificationLabellingHelper.SplitType)2 BufferedImage (java.awt.image.BufferedImage)1 BufferedInputStream (java.io.BufferedInputStream)1 BufferedOutputStream (java.io.BufferedOutputStream)1 FileInputStream (java.io.FileInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 FileOutputStream (java.io.FileOutputStream)1