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;
}
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);
}
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);
}
}
}
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);
}
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));
}
Aggregations