use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class RetainedTrainingObjects method put.
Map<PathClass, List<PathObject>> put(final String key, final Map<PathClass, List<PathObject>> value) {
if (key == null)
throw new IllegalArgumentException("Cannot retain objects without a key! Do you have a project open?");
// Also, we create a new map to ensure it's sorted
Map<PathClass, List<PathObject>> newMap = new TreeMap<>();
for (PathClass pathClass : value.keySet()) {
List<PathObject> originalList = value.get(pathClass);
List<PathObject> newList = originalList.stream().map(p -> {
if (p.isDetection())
return PathObjects.createDetectionObject(p.getROI(), p.getPathClass(), p.getMeasurementList());
else {
logger.debug("Adding non-detection object to retained map: {}", p);
return p;
}
}).collect(Collectors.toList());
newMap.put(pathClass, newList);
value.put(pathClass, newList);
}
return retainedObjectsMap.put(key, value);
}
use of qupath.lib.objects.classes.PathClass 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.objects.classes.PathClass in project qupath by qupath.
the class TestPixelClassifierTools method checkCreateObjects.
private void checkCreateObjects(ImageServer<BufferedImage> server, int[] hist, Map<PathClass, Integer> classificationLabelsReverse) throws IOException {
var hierarchy = new PathObjectHierarchy();
boolean success = PixelClassifierTools.createObjectsFromPredictions(server, hierarchy, Collections.singleton(hierarchy.getRootObject()), r -> PathObjects.createAnnotationObject(r), 0, 0);
assertTrue(success);
// Recall that we have an object for zero as well
var annotations = new ArrayList<>(hierarchy.getAnnotationObjects());
assertEquals(hist.length, annotations.size());
// Check areas for all our annotations
Collections.sort(annotations, Comparator.comparingInt(a -> classificationLabelsReverse.get(a.getPathClass())));
for (var annotation : annotations) {
int label = classificationLabelsReverse.get(annotation.getPathClass());
var roi = annotation.getROI();
double area = roi.getArea();
if (printAreas)
logger.debug(hist[label] + ": \t" + area);
assertEquals(hist[label], area);
var geom = roi.getGeometry();
if (alwaysCheckValidity || geom.getNumPoints() < MAX_POINTS_FOR_VALIDITY) {
var error = new IsValidOp(geom).getValidationError();
if (error != null)
logger.warn("{}", error);
assertNull(error);
}
assertEquals(hist[label], geom.getArea());
}
}
use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class DistanceTools method detectionCentroidDistances.
/**
* Compute the distance for all detection object centroids to the closest annotation with each valid, not-ignored classification and add
* the result to the detection measurement list.
* @param imageData
* @param splitClassNames if true, split the classification name. For example, if an image contains classifications for both "CD3: CD4" and "CD3: CD8",
* distances will be calculated for all components (e.g. "CD3", "CD4" and "CD8").
*/
public static void detectionCentroidDistances(ImageData<?> imageData, boolean splitClassNames) {
var server = imageData.getServer();
var hierarchy = imageData.getHierarchy();
var detections = hierarchy.getCellObjects();
if (detections.isEmpty())
detections = hierarchy.getDetectionObjects();
// TODO: Support TMA cores
if (hierarchy.getTMAGrid() != null)
logger.warn("Detection centroid distances command currently ignores TMA grid information!");
var pathClasses = detections.stream().map(p -> p.getPathClass()).filter(p -> p != null && p.isValid() && !PathClassTools.isIgnoredClass(p)).collect(Collectors.toSet());
var cal = server.getPixelCalibration();
String xUnit = cal.getPixelWidthUnit();
String yUnit = cal.getPixelHeightUnit();
double pixelWidth = cal.getPixelWidth().doubleValue();
double pixelHeight = cal.getPixelHeight().doubleValue();
if (!xUnit.equals(yUnit))
throw new IllegalArgumentException("Pixel width & height units do not match! Width " + xUnit + ", height " + yUnit);
String unit = xUnit;
for (PathClass pathClass : pathClasses) {
if (splitClassNames) {
var names = PathClassTools.splitNames(pathClass);
for (var name : names) {
logger.debug("Computing distances for {}", pathClass);
var filteredDetections = detections.stream().filter(a -> PathClassTools.containsName(a.getPathClass(), name)).collect(Collectors.toList());
if (!filteredDetections.isEmpty()) {
String measurementName = "Distance to detection with " + name + " " + unit;
centroidToCentroidDistance2D(detections, filteredDetections, pixelWidth, pixelHeight, measurementName);
}
}
} else {
logger.debug("Computing distances for {}", pathClass);
var filteredDetections = detections.stream().filter(a -> a.getPathClass() == pathClass).collect(Collectors.toList());
if (!filteredDetections.isEmpty()) {
String name = "Distance to detection " + pathClass + " " + unit;
centroidToCentroidDistance2D(detections, filteredDetections, pixelWidth, pixelHeight, name);
}
}
}
hierarchy.fireObjectMeasurementsChangedEvent(DistanceTools.class, detections);
}
use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class ClassifierBuilderPane method exportTrainingFeatures.
private boolean exportTrainingFeatures(final File file) {
// First, add existing objects to map
ImageData<?> imageData = getImageData();
// Get the features to export
List<String> features = featurePanel.getSelectedFeatures();
// Write the header
PrintWriter writer;
try {
writer = new PrintWriter(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
boolean includePath = !retainedObjectsMap.isEmpty();
// String delim = "\t";
String delim = ",";
if (includePath) {
writer.print("Image");
writer.print(delim);
}
writer.print("Class");
for (String feature : features) {
writer.print(delim);
// Make sure we replace the delimiter so we don't have trouble
writer.print(feature.replace(delim, "-"));
}
writer.println();
// Write the current objects
String currentPath = null;
if (imageData != null) {
currentPath = imageData.getServerPath();
Map<PathClass, List<PathObject>> map = getTrainingMap();
for (Entry<PathClass, List<PathObject>> entry : map.entrySet()) {
for (PathObject pathObject : entry.getValue()) {
if (includePath) {
writer.print(currentPath);
writer.print(delim);
}
writer.print(entry.getKey().getName());
writer.print(delim);
for (String name : features) {
writer.print(Double.toString(pathObject.getMeasurementList().getMeasurementValue(name)));
writer.print(delim);
}
writer.println();
}
}
}
writer.close();
return true;
}
Aggregations