use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class ClassifierBuilderPane method showRetainedTrainingMap.
void showRetainedTrainingMap(final RetainedTrainingObjects retainedObjects) {
Map<String, Map<PathClass, List<PathObject>>> map = retainedObjects.getMap();
// Determine columns
Set<PathClass> pathClasses = new TreeSet<>();
for (Map<PathClass, List<PathObject>> temp : map.values()) {
pathClasses.addAll(temp.keySet());
}
// Don't show a badly-formed table with nothing in it...
if (pathClasses.isEmpty()) {
Dialogs.showMessageDialog("Training objects", "No training objects selected!");
return;
}
// Set up table
TableView<String> table = new TableView<>();
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.getItems().setAll(map.keySet());
Collections.sort(table.getItems());
// Create columns
TableColumn<String, String> colName = new TableColumn<>("Image");
colName.setCellValueFactory(column -> new ReadOnlyObjectWrapper<>(column.getValue()));
// colName.setCellValueFactory(column -> new ReadOnlyObjectWrapper<>(ServerTools.getDefaultShortServerName(column.getValue())));
colName.setPrefWidth(240);
table.getColumns().add(colName);
int nColWidth = 80;
for (PathClass pathClass : pathClasses) {
TableColumn<String, Integer> col = new TableColumn<>(pathClass.getName());
col.setCellValueFactory(column -> {
if (map.get(column.getValue()).get(pathClass) == null)
return new ReadOnlyObjectWrapper<Integer>(0);
else
return new ReadOnlyObjectWrapper<Integer>(map.get(column.getValue()).get(pathClass).size());
});
col.setPrefWidth(nColWidth);
table.getColumns().add(col);
}
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
// Show
Stage dialog = new Stage();
dialog.initOwner(qupath.getStage());
dialog.setTitle("Training objects");
dialog.setScene(new Scene(table));
dialog.showAndWait();
}
use of qupath.lib.objects.classes.PathClass 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();
}
use of qupath.lib.objects.classes.PathClass 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;
}
use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class PathClassificationLabellingHelper method resampleClassificationMap.
/**
* Resample a training map (PathClass label & 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;
}
use of qupath.lib.objects.classes.PathClass 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;
}
Aggregations