Search in sources :

Example 51 with PathClass

use of qupath.lib.objects.classes.PathClass in project qupath by qupath.

the class DefaultProject method writePathClasses.

void writePathClasses(Collection<PathClass> pathClasses) throws IOException {
    var path = Paths.get(ensureDirectoryExists(getClassifiersPath()).toString(), "classes.json");
    if (pathClasses == null || pathClasses.isEmpty()) {
        Files.deleteIfExists(path);
        return;
    }
    JsonArray pathClassArray = new JsonArray();
    for (PathClass pathClass : pathClasses) {
        JsonObject jsonEntry = new JsonObject();
        jsonEntry.addProperty("name", pathClass.toString());
        jsonEntry.addProperty("color", pathClass.getColor());
        pathClassArray.add(jsonEntry);
    }
    var element = new JsonObject();
    element.add("pathClasses", pathClassArray);
    try (var writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) {
        GsonTools.getInstance(true).toJson(element, writer);
    }
}
Also used : JsonArray(com.google.gson.JsonArray) PathClass(qupath.lib.objects.classes.PathClass) JsonObject(com.google.gson.JsonObject)

Example 52 with PathClass

use of qupath.lib.objects.classes.PathClass in project qupath by qupath.

the class QuPathGUI method savePathClasses.

/**
 * Save available PathClasses to preferences.
 */
private void savePathClasses() {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    try (ObjectOutputStream out = new ObjectOutputStream(stream)) {
        List<PathClass> pathClasses = new ArrayList<>(availablePathClasses);
        out.writeObject(pathClasses);
        out.flush();
    } catch (IOException e) {
        logger.error("Error saving classes", e);
    }
    byte[] bytes = stream.toByteArray();
    if (bytes.length < 0.75 * Preferences.MAX_VALUE_LENGTH)
        PathPrefs.getUserPreferences().putByteArray("defaultPathClasses", bytes);
    else
        logger.error("Classification list too long ({} bytes) - cannot save it to the preferences.", bytes.length);
}
Also used : PathClass(qupath.lib.objects.classes.PathClass) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ObjectOutputStream(java.io.ObjectOutputStream)

Example 53 with PathClass

use of qupath.lib.objects.classes.PathClass in project qupath by qupath.

the class QuPathGUI method updateSetAnnotationPathClassMenu.

void updateSetAnnotationPathClassMenu(final ObservableList<MenuItem> menuSetClassItems, final QuPathViewer viewer, final boolean useFancyIcons) {
    // We need a viewer and an annotation, as well as some PathClasses, otherwise we just need to ensure the menu isn't visible
    if (viewer == null || !(viewer.getSelectedObject() instanceof PathAnnotationObject) || availablePathClasses.isEmpty()) {
        menuSetClassItems.clear();
        return;
    }
    PathObject mainPathObject = viewer.getSelectedObject();
    PathClass currentClass = mainPathObject.getPathClass();
    ToggleGroup group = new ToggleGroup();
    List<MenuItem> itemList = new ArrayList<>();
    RadioMenuItem selected = null;
    for (PathClass pathClass : availablePathClasses) {
        PathClass pathClassToSet = pathClass.getName() == null ? null : pathClass;
        String name = pathClass.getName() == null ? "None" : pathClass.toString();
        Action actionSetClass = new Action(name, e -> {
            List<PathObject> changed = new ArrayList<>();
            for (PathObject pathObject : viewer.getAllSelectedObjects()) {
                if (!pathObject.isAnnotation() || pathObject.getPathClass() == pathClassToSet)
                    continue;
                pathObject.setPathClass(pathClassToSet);
                changed.add(pathObject);
            }
            if (!changed.isEmpty())
                viewer.getHierarchy().fireObjectClassificationsChangedEvent(this, changed);
        });
        Node shape;
        if (useFancyIcons) {
            Ellipse r = new Ellipse(TOOLBAR_ICON_SIZE / 2.0, TOOLBAR_ICON_SIZE / 2.0, TOOLBAR_ICON_SIZE, TOOLBAR_ICON_SIZE);
            if ("None".equals(name)) {
                r.setFill(Color.rgb(255, 255, 255, 0.75));
            } else
                r.setFill(ColorToolsFX.getCachedColor(pathClass.getColor()));
            r.setOpacity(0.8);
            DropShadow effect = new DropShadow(6, -3, 3, Color.GRAY);
            r.setEffect(effect);
            shape = r;
        } else {
            Rectangle r = new Rectangle(0, 0, 8, 8);
            r.setFill("None".equals(name) ? Color.TRANSPARENT : ColorToolsFX.getCachedColor(pathClass.getColor()));
            shape = r;
        }
        // actionSetClass.setGraphic(r);
        RadioMenuItem item = ActionUtils.createRadioMenuItem(actionSetClass);
        item.graphicProperty().unbind();
        item.setGraphic(shape);
        item.setToggleGroup(group);
        itemList.add(item);
        if (pathClassToSet == currentClass)
            selected = item;
    }
    group.selectToggle(selected);
    menuSetClassItems.setAll(itemList);
}
Also used : Action(org.controlsfx.control.action.Action) Ellipse(javafx.scene.shape.Ellipse) Node(javafx.scene.Node) ArrayList(java.util.ArrayList) Rectangle(javafx.scene.shape.Rectangle) MenuItem(javafx.scene.control.MenuItem) CheckMenuItem(javafx.scene.control.CheckMenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) RadioMenuItem(javafx.scene.control.RadioMenuItem) RadioMenuItem(javafx.scene.control.RadioMenuItem) DropShadow(javafx.scene.effect.DropShadow) PathClass(qupath.lib.objects.classes.PathClass) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) ToggleGroup(javafx.scene.control.ToggleGroup)

Example 54 with PathClass

use of qupath.lib.objects.classes.PathClass in project qupath by qupath.

the class ColorModelFactory method getIndexedClassificationColorModel.

/**
 * Get a ColorModel suitable for showing output pixel classifications, using an 8-bit or 16-bit labeled image.
 *
 * @param channels
 * @return
 */
public static IndexColorModel getIndexedClassificationColorModel(Map<Integer, PathClass> channels) {
    var stats = channels.keySet().stream().mapToInt(c -> c).summaryStatistics();
    if (stats.getMin() < 0)
        throw new IllegalArgumentException("Minimum label must be >= 0");
    int length = stats.getMax() + 1;
    int[] cmap = new int[length];
    for (var entry : channels.entrySet()) {
        var pathClass = entry.getValue();
        if (pathClass == null || pathClass == PathClassFactory.getPathClassUnclassified()) {
            cmap[entry.getKey()] = ColorTools.packARGB(0, 255, 255, 255);
        } else if (PathClassTools.isIgnoredClass(entry.getValue())) {
            var color = pathClass == null ? 0 : pathClass.getColor();
            int alpha = 192;
            if (pathClass == PathClassFactory.getPathClass(StandardPathClasses.IGNORE))
                alpha = 32;
            cmap[entry.getKey()] = ColorTools.packARGB(alpha, ColorTools.red(color), ColorTools.green(color), ColorTools.blue(color));
        } else
            cmap[entry.getKey()] = entry.getValue().getColor();
    }
    if (cmap.length <= 256)
        return new IndexColorModel(8, length, cmap, 0, true, -1, DataBuffer.TYPE_BYTE);
    else if (cmap.length <= 65536)
        return new IndexColorModel(16, length, cmap, 0, true, -1, DataBuffer.TYPE_USHORT);
    else
        throw new IllegalArgumentException("Only 65536 possible classifications supported!");
}
Also used : PathClassTools(qupath.lib.objects.classes.PathClassTools) LoggerFactory(org.slf4j.LoggerFactory) ImageChannel(qupath.lib.images.servers.ImageChannel) HashMap(java.util.HashMap) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) DataBufferShort(java.awt.image.DataBufferShort) ArrayList(java.util.ArrayList) DataBufferDouble(java.awt.image.DataBufferDouble) BandedSampleModel(java.awt.image.BandedSampleModel) Map(java.util.Map) IndexColorModel(java.awt.image.IndexColorModel) Raster(java.awt.image.Raster) StandardPathClasses(qupath.lib.objects.classes.PathClassFactory.StandardPathClasses) Logger(org.slf4j.Logger) ColorTools(qupath.lib.common.ColorTools) ColorMap(qupath.lib.color.ColorMaps.ColorMap) GeneralTools(qupath.lib.common.GeneralTools) PixelType(qupath.lib.images.servers.PixelType) PathClass(qupath.lib.objects.classes.PathClass) DoubleToIntFunction(java.util.function.DoubleToIntFunction) Objects(java.util.Objects) List(java.util.List) ColorModel(java.awt.image.ColorModel) WritableRaster(java.awt.image.WritableRaster) DataBufferFloat(java.awt.image.DataBufferFloat) Collections(java.util.Collections) DataBuffer(java.awt.image.DataBuffer) IndexColorModel(java.awt.image.IndexColorModel)

Example 55 with PathClass

use of qupath.lib.objects.classes.PathClass in project qupath by qupath.

the class PathIntensityClassifier method classifyPathObjects.

/**
 * Classify the intensity of a collection of objects, based on the current thresholds. <p>
 * If an object is missing the required measurement, its {@link PathClass} remains unchanged.
 *
 * @param pathObjects
 */
@Override
public int classifyPathObjects(Collection<PathObject> pathObjects) {
    int counter = 0;
    // If there is no class specified, apply to all
    if (classSelected == null) {
        if (singleThreshold)
            PathClassifierTools.setIntensityClassifications(pathObjects, intensityMeasurement, t1);
        else
            PathClassifierTools.setIntensityClassifications(pathObjects, intensityMeasurement, t1, t2, t3);
        return pathObjects.size();
    }
    // Ensure we have the correct singleton class so we can do an equality check
    classSelected = PathClassFactory.getSingletonPathClass(classSelected);
    PathClass classPositive = PathClassFactory.getPositive(classSelected);
    PathClass classNegative = PathClassFactory.getNegative(classSelected);
    PathClass classOnePlus = PathClassFactory.getOnePlus(classSelected);
    PathClass classTwoPlus = PathClassFactory.getTwoPlus(classSelected);
    PathClass classThreePlus = PathClassFactory.getThreePlus(classSelected);
    // Because the classifications are really sub-classifications, retain the same probability
    for (PathObject pathObjectTemp : pathObjects) {
        if (classSelected == null || pathObjectTemp.getPathClass() == null || !(pathObjectTemp.getPathClass().isDerivedFrom(classSelected) || pathObjectTemp.getPathClass().getName().equals(classSelected.getName())))
            // if (classSelected == null || pathObjectTemp.getPathClass() == null || !pathObjectTemp.getPathClass().getName().equals(classSelected.getName()))
            continue;
        Object value = pathObjectTemp.getMeasurementList().getMeasurementValue(intensityMeasurement);
        if (!(value instanceof Number))
            continue;
        double val = ((Number) value).doubleValue();
        // If measurement is missing, do not change it
        if (Double.isNaN(val))
            continue;
        else if (singleThreshold) {
            if (val > t1)
                pathObjectTemp.setPathClass(classPositive, pathObjectTemp.getClassProbability());
            else
                pathObjectTemp.setPathClass(classNegative, pathObjectTemp.getClassProbability());
        } else {
            if (val > t3)
                pathObjectTemp.setPathClass(classThreePlus, pathObjectTemp.getClassProbability());
            else if (val > t2)
                pathObjectTemp.setPathClass(classTwoPlus, pathObjectTemp.getClassProbability());
            else if (val > t1)
                pathObjectTemp.setPathClass(classOnePlus, pathObjectTemp.getClassProbability());
            else
                pathObjectTemp.setPathClass(classNegative, pathObjectTemp.getClassProbability());
        }
        counter++;
    }
    return counter;
}
Also used : PathClass(qupath.lib.objects.classes.PathClass) PathObject(qupath.lib.objects.PathObject) PathObject(qupath.lib.objects.PathObject)

Aggregations

PathClass (qupath.lib.objects.classes.PathClass)66 ArrayList (java.util.ArrayList)42 PathObject (qupath.lib.objects.PathObject)34 List (java.util.List)29 Map (java.util.Map)25 IOException (java.io.IOException)21 Logger (org.slf4j.Logger)20 LoggerFactory (org.slf4j.LoggerFactory)20 Collections (java.util.Collections)17 Collectors (java.util.stream.Collectors)17 BufferedImage (java.awt.image.BufferedImage)16 LinkedHashMap (java.util.LinkedHashMap)16 ROI (qupath.lib.roi.interfaces.ROI)16 HashMap (java.util.HashMap)15 ImageData (qupath.lib.images.ImageData)15 PathClassFactory (qupath.lib.objects.classes.PathClassFactory)15 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)15 ParameterList (qupath.lib.plugins.parameters.ParameterList)15 Collection (java.util.Collection)14 TreeMap (java.util.TreeMap)11