Search in sources :

Example 1 with Parameterizable

use of qupath.lib.plugins.parameters.Parameterizable in project qupath by qupath.

the class OpenCvClassifier method getDescription.

// @Override
// public int classifyPathObjects(Collection<PathObject> pathObjects) {
// 
// 
// int counter = 0;
// Mat samples = new Mat(1, measurements.size(), CvType.CV_32FC1);
// 
// for (PathObject pathObject : pathObjects) {
// MeasurementList measurementList = pathObject.getMeasurementList();
// int idx = 0;
// for (String m : measurements) {
// double value = measurementList.getMeasurementValue(m);
// samples.put(0, idx, value);
// idx++;
// }
// 
// float prediction = trees.predict(samples);
// 
// //			if (computeProbabilities) {
// //				double prediction = svm.svm_predict_probability(model, nodes, probabilities);
// //				int index = (int)prediction;
// //				pathObject.setPathClass(pathClasses.get(index), probabilities[index]);
// //			} else {
// //				double prediction = svm.svm_predict(model, nodes);
// pathObject.setPathClass(pathClasses.get((int)prediction));
// //			}
// counter++;
// }
// 
// return counter;
// }
@Override
public String getDescription() {
    if (classifier == null)
        return "No classifier set!";
    StringBuilder sb = new StringBuilder();
    String mainString = getName() + (!isValid() ? " (not trained)" : "");
    ;
    sb.append("Classifier:\t").append(mainString).append("\n\n");
    sb.append("Classes:\t[");
    Iterator<PathClass> iterClasses = getPathClasses().iterator();
    while (iterClasses.hasNext()) {
        sb.append(iterClasses.next());
        if (iterClasses.hasNext())
            sb.append(", ");
        else
            sb.append("]\n\n");
    }
    sb.append("Normalization:\t").append(normalization).append("\n\n");
    if (this instanceof Parameterizable) {
        ParameterList params = ((Parameterizable) this).getParameterList();
        String paramString = ParameterList.getParameterListJSON(params, "\n  ");
        sb.append("Main parameters:\n  ").append(paramString);
        sb.append("\n\n");
    }
    List<String> measurements = getRequiredMeasurements();
    sb.append("Required measurements (").append(measurements.size()).append("):\n");
    Iterator<String> iter = getRequiredMeasurements().iterator();
    while (iter.hasNext()) {
        sb.append("    ");
        sb.append(iter.next());
        sb.append("\n");
    }
    return sb.toString();
// return getName() + (!isValid() ? " (not trained)" : "");
}
Also used : PathClass(qupath.lib.objects.classes.PathClass) Parameterizable(qupath.lib.plugins.parameters.Parameterizable) ParameterList(qupath.lib.plugins.parameters.ParameterList)

Example 2 with Parameterizable

use of qupath.lib.plugins.parameters.Parameterizable in project qupath by qupath.

the class ClassifierBuilderPane method initializeBuildPanel.

private void initializeBuildPanel() {
    Button btnUpdateClassifier = new Button("Build & Apply");
    btnUpdateClassifier.setTooltip(new Tooltip("Build classifier & apply to objects in the current image"));
    tbAutoUpdate.setTooltip(new Tooltip("Automatically update the classification when changes are made to the data - only recommended if the classifier is fast & the amount of training data is small"));
    tbAutoUpdate.setOnAction(e -> {
        if (!tbAutoUpdate.isDisabled() && tbAutoUpdate.isSelected())
            updateClassification(true);
    });
    panelUpdate = new ParameterPanelFX(paramsUpdate);
    // panelUpdate.getPane().setPadding(new Insets(0, 10, 0, 10));
    comboClassifiers.setOnAction(e -> {
        maybeUpdate();
        // WekaClassifierBuilder builder = (WekaClassifierBuilder)comboClassifiers.getSelectedItem();
        // We can't auto-update if we don't have a valid (non-advanced) classifier builder
        // cbAutoUpdate.setEnabled(builder != null && builder.getClassifierClass() != null);
        classifier = (T) comboClassifiers.getSelectionModel().getSelectedItem();
        // Enable/disable edit button
        if (btnEdit != null)
            btnEdit.setDisable(!(classifier instanceof Parameterizable));
        tbAutoUpdate.setDisable(classifier == null || !classifier.supportsAutoUpdate());
    });
    // Make panel to create a classifier
    GridPane panelClassifierType = new GridPane();
    panelClassifierType.add(new Label("Classifier type: "), 0, 0);
    panelClassifierType.add(comboClassifiers, 1, 0);
    comboClassifiers.setMaxWidth(Double.MAX_VALUE);
    comboClassifiers.setTooltip(new Tooltip("Choose classifier type"));
    GridPane.setHgrow(comboClassifiers, Priority.ALWAYS);
    panelClassifierType.setHgap(5);
    panelClassifierType.setVgap(5);
    // Add in options button
    btnEdit = new Button("Edit");
    btnEdit.setTooltip(new Tooltip("Edit advanced classifier options"));
    btnEdit.setDisable(!(classifier instanceof Parameterizable));
    btnEdit.setOnAction(e -> {
        if (!(classifier instanceof Parameterizable)) {
            Dialogs.showErrorMessage("Classifier settings", "No options available for selected classifier!");
            return;
        }
        Parameterizable parameterizable = (Parameterizable) classifier;
        ParameterPanelFX panel = new ParameterPanelFX(parameterizable.getParameterList());
        // JDialog dialog = new JDialog(qupath.getFrame(), "Classifier settings", ModalityType.APPLICATION_MODAL);
        BorderPane pane = new BorderPane();
        pane.setCenter(panel.getPane());
        Button btnRun = new Button("Rebuild classifier");
        btnRun.setOnAction(e2 -> updateClassification(true));
        pane.setBottom(btnRun);
        Dialogs.showMessageDialog("Classifier settings", pane);
    });
    panelClassifierType.add(btnEdit, 2, 0);
    panelClassifierType.add(tbAutoUpdate, 3, 0);
    panelClassifierType.add(btnUpdateClassifier, 4, 0);
    panelClassifierType.setPadding(new Insets(10, 10, 10, 10));
    // Make feature panel
    GridPane panelFeatures = new GridPane();
    Button btnFeatures = new Button("Select...");
    btnFeatures.setTooltip(new Tooltip("Select features to use for classification - this is required before any classifier can be made"));
    btnFeatures.setOnAction(e -> {
        qupath.submitShortTask(() -> featurePanel.ensureMeasurementsUpdated());
        Dialogs.showMessageDialog("Select Features", featurePanel.getPanel());
        updateSelectedFeaturesLabel();
    });
    Button btnUseAllFeatures = new Button("Use all");
    btnUseAllFeatures.setTooltip(new Tooltip("Update feature list to use all available features"));
    btnUseAllFeatures.setOnAction(e -> selectAllFeatures());
    panelFeatures.add(labelSelectedFeatures, 0, 0);
    GridPane.setHgrow(labelSelectedFeatures, Priority.ALWAYS);
    labelSelectedFeatures.setMaxWidth(Double.MAX_VALUE);
    // labelSelectedFeatures.setTextAlignment(TextAlignment.CENTER);
    // labelSelectedFeatures.setAlignment(Pos.CENTER);
    panelFeatures.add(btnFeatures, 1, 0);
    panelFeatures.add(btnUseAllFeatures, 2, 0);
    panelFeatures.setHgap(5);
    // Multi-image stuff
    GridPane panelSouth = new GridPane();
    // Tooltip.install(btnResetTrainingObjects, new Tooltip("Reset all the retained objects, so that the classifier only uses the training objects from the current image"));
    miResetTrainingObjects.setOnAction(e -> {
        if (retainedObjectsMap == null || retainedObjectsMap.isEmpty())
            return;
        int nObjects = retainedObjectsMap.countRetainedObjects();
        String message = nObjects == 1 ? "Remove one retained object from classifier training?" : "Remove " + nObjects + " retained objects from classifier training?";
        if (Dialogs.showYesNoDialog("Remove retained objects", message)) {
            retainedObjectsMap.clear();
            updateRetainedObjectsLabel();
        }
    });
    final String trainingExtension = "qptrain";
    miLoadTrainingObjects.setOnAction(e -> {
        File fileTraining = Dialogs.promptForFile("Load objects", null, trainingExtension, new String[] { trainingExtension });
        if (fileTraining == null)
            return;
        if (!loadRetainedObjects(fileTraining)) {
            Dialogs.showErrorMessage("Load training objects", "There was an error loading training objects from \n" + fileTraining);
        }
    });
    // btnSaveTrainingObjects.setTooltip(new Tooltip("Load training objects saved in a previous session"));
    miSaveTrainingObjects.setOnAction(e -> {
        File fileTraining = Dialogs.promptToSaveFile("Save objects", null, null, trainingExtension, trainingExtension);
        if (fileTraining == null)
            return;
        if (!saveRetainedObjects(fileTraining)) {
            Dialogs.showErrorMessage("Save training objects", "There was an error saving training objects to \n" + fileTraining);
        }
    });
    // btnSaveTrainingObjects.setTooltip(new Tooltip("Save training objects for reloading in another session"));
    miExportTrainingFeatures.setOnAction(e -> {
        File fileTraining = Dialogs.promptToSaveFile("Export features", null, null, "Text file", "txt");
        if (fileTraining == null)
            return;
        if (!exportTrainingFeatures(fileTraining)) {
            Dialogs.showErrorMessage("Export features", "There was an exporting the training features to \n" + fileTraining);
        }
    });
    // btnExportTrainingFeatures.setTooltip(new Tooltip("Export training features to a text file (e.g. for analysis elsewhere"));
    // btnRebuildTrainingFromProject.setTooltip(new Tooltip("Load training objects from all images in the project to use these to create a single classifier"));
    miRebuildTrainingFromProject.setOnAction(e -> {
        loadAllTrainingSamplesForProject();
    });
    miClassifyAllImagesInProject.setOnAction(e -> {
        classifyAllImagesInProject();
    });
    miCrossValidateAcrossImages.setOnAction(e -> {
        crossValidateAcrossImages();
    });
    labelRetainedObjects.setTooltip(new Tooltip("The total number of objects last used for training - including from other images not currently open"));
    // labelRetainedObjects.setAlignment(Pos.CENTER);
    labelRetainedObjects.setMaxWidth(Double.MAX_VALUE);
    // labelRetainedObjects.setPadding(new Insets(5, 5, 5, 5));
    panelSouth.add(labelRetainedObjects, 0, 0);
    GridPane.setHgrow(labelRetainedObjects, Priority.ALWAYS);
    // panelSouth.setStyle("-fx-background-color: red;");
    MenuItem miShowTrainingObjectMatrix = new MenuItem("Show training object counts");
    miShowTrainingObjectMatrix.setOnAction(e -> {
        updateRetainedObjectsMap();
        showRetainedTrainingMap(retainedObjectsMap);
    });
    ContextMenu context = new ContextMenu();
    context.getItems().addAll(miLoadTrainingObjects, miSaveTrainingObjects, miRebuildTrainingFromProject, new SeparatorMenuItem(), miShowTrainingObjectMatrix, miResetTrainingObjects, new SeparatorMenuItem(), miExportTrainingFeatures, miCrossValidateAcrossImages, miClassifyAllImagesInProject);
    context.setOnShowing(e -> {
        boolean hasRetainedObjects = !retainedObjectsMap.isEmpty();
        boolean hasAnyObjects = hasRetainedObjects || (getHierarchy() != null && !getHierarchy().isEmpty());
        miResetTrainingObjects.setDisable(!hasRetainedObjects);
        miCrossValidateAcrossImages.setDisable(!hasRetainedObjects);
        miSaveTrainingObjects.setDisable(!hasAnyObjects);
        miExportTrainingFeatures.setDisable(!hasAnyObjects);
        miRebuildTrainingFromProject.setVisible(qupath.getProject() != null);
        miClassifyAllImagesInProject.setVisible(qupath.getProject() != null);
    });
    Button buttonMore = new Button("More...");
    buttonMore.setOnMouseClicked(e -> {
        context.show(buttonMore, e.getScreenX(), e.getScreenY());
    });
    panelSouth.add(buttonMore, 1, 0);
    // panelSouth.setBottom(panelRetainingButtons);
    updateRetainedObjectsLabel();
    // TitledPane multiImage = new TitledPane("Multi-image training", panelSouth);
    // labelRetainedObjects.prefWidthProperty().bind(multiImage.widthProperty());
    // panelClassifier.getChildren().add(multiImage);
    // panelSouth.add(panelRetaining, BorderLayout.NORTH);
    // panelSouth.add(btnSaveClassifier, BorderLayout.SOUTH);
    // panelFeatures.setStyle("-fx-background-color: blue;");
    GridPane paneAdvancedMain = new GridPane();
    paneAdvancedMain.add(panelFeatures, 0, 0);
    paneAdvancedMain.add(panelSouth, 0, 1);
    paneAdvancedMain.add(panelUpdate.getPane(), 0, 2);
    paneAdvancedMain.setVgap(5);
    panelUpdate.getPane().setMaxWidth(Double.MAX_VALUE);
    GridPane.setHgrow(panelFeatures, Priority.ALWAYS);
    GridPane.setHgrow(panelSouth, Priority.ALWAYS);
    GridPane.setHgrow(panelUpdate.getPane(), Priority.ALWAYS);
    // panelUpdate.getPane().setStyle("-fx-background-color: green;");
    TitledPane paneAdvanced = new TitledPane("Advanced options", paneAdvancedMain);
    paneAdvanced.setMaxWidth(Double.MAX_VALUE);
    paneAdvanced.setExpanded(false);
    // Really, I should probably just use a CSS stylesheet somewhere... here is an inelegant way to change things...
    Platform.runLater(() -> {
        try {
            paneAdvanced.lookup(".title").setStyle("-fx-background-color: transparent");
            paneAdvanced.lookup(".title").setEffect(null);
            paneAdvanced.lookup(".content").setStyle("-fx-border-color: null");
        } catch (Exception e) {
            logger.error("Error setting Advanced options pane style", e);
        }
    });
    panelClassifierType.add(paneAdvanced, 0, 1, 6, 1);
    progressIndicator.setVisible(false);
    progressIndicator.setPrefSize(30, 30);
    panelClassifierType.add(progressIndicator, 5, 0, 1, 1);
    // panelClassifierType.add(panelUpdate.getPane(), 0, 1, 4, 1);
    GridPane.setHgrow(panelUpdate.getPane(), Priority.ALWAYS);
    GridPane.setHgrow(paneAdvanced, Priority.ALWAYS);
    // btnUpdateClassifier.setMaxWidth(Double.MAX_VALUE);
    // panelClassifierType.add(btnUpdateClassifier, 0, 2, 3, 1);
    panelClassifier.getChildren().add(new TitledPane("Classifier", panelClassifierType));
    panelIntensities.intensityFeatureProperty().addListener((v, o, n) -> updateIntensityPanelCallback());
    panelIntensities.addThresholdParameterChangeListener((p, k, a) -> updateIntensityPanelCallback());
    panelClassifier.getChildren().add(new TitledPane("Intensity", panelIntensities.getPane()));
    btnUpdateClassifier.setOnAction(e -> updateClassification(true));
}
Also used : TitledPane(javafx.scene.control.TitledPane) BorderPane(javafx.scene.layout.BorderPane) GridPane(javafx.scene.layout.GridPane) Insets(javafx.geometry.Insets) Tooltip(javafx.scene.control.Tooltip) Label(javafx.scene.control.Label) MenuItem(javafx.scene.control.MenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) ContextMenu(javafx.scene.control.ContextMenu) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) ParameterPanelFX(qupath.lib.gui.dialogs.ParameterPanelFX) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) Button(javafx.scene.control.Button) ToggleButton(javafx.scene.control.ToggleButton) Parameterizable(qupath.lib.plugins.parameters.Parameterizable) File(java.io.File)

Aggregations

Parameterizable (qupath.lib.plugins.parameters.Parameterizable)2 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 Insets (javafx.geometry.Insets)1 Button (javafx.scene.control.Button)1 ContextMenu (javafx.scene.control.ContextMenu)1 Label (javafx.scene.control.Label)1 MenuItem (javafx.scene.control.MenuItem)1 SeparatorMenuItem (javafx.scene.control.SeparatorMenuItem)1 TitledPane (javafx.scene.control.TitledPane)1 ToggleButton (javafx.scene.control.ToggleButton)1 Tooltip (javafx.scene.control.Tooltip)1 BorderPane (javafx.scene.layout.BorderPane)1 GridPane (javafx.scene.layout.GridPane)1 ParameterPanelFX (qupath.lib.gui.dialogs.ParameterPanelFX)1 PathClass (qupath.lib.objects.classes.PathClass)1 ParameterList (qupath.lib.plugins.parameters.ParameterList)1