use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.
the class PathObjectIOTest method test_IOObjectsGeoJSONImpl.
private void test_IOObjectsGeoJSONImpl(boolean keepMeasurements, GeoJsonExportOptions... options) throws IOException {
ROI roiDetection = ROIs.createRectangleROI(0, 0, 10, 10, ImagePlane.getDefaultPlane());
ROI roiAnnotation = ROIs.createRectangleROI(100, 100, 10, 10, ImagePlane.getDefaultPlane());
ROI roiCell1 = ROIs.createRectangleROI(25, 25, 25, 25, ImagePlane.getDefaultPlane());
ROI roiCell2 = ROIs.createRectangleROI(12, 12, 5, 5, ImagePlane.getDefaultPlane());
ROI roiTile = ROIs.createRectangleROI(100, 100, 10, 10, ImagePlane.getDefaultPlane());
MeasurementList mlDetection = MeasurementListFactory.createMeasurementList(16, MeasurementList.MeasurementListType.GENERAL);
MeasurementList mlCell = MeasurementListFactory.createMeasurementList(16, MeasurementList.MeasurementListType.GENERAL);
PathObject myPDO = PathObjects.createDetectionObject(roiDetection, PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK), mlDetection);
PathObject myPAO = PathObjects.createAnnotationObject(roiAnnotation, PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK));
PathObject myPCO = PathObjects.createCellObject(roiCell1, roiCell2, PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN), mlCell);
PathObject myPTO = PathObjects.createTileObject(roiTile, PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN), null);
PathObject myTMA = PathObjects.createTMACoreObject(25, 25, 25, false);
Collection<PathObject> objs = Arrays.asList(myPDO, myPCO, myPAO, myPTO, myTMA);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// Add measurements
mlDetection.addMeasurement("TestMeasurement1", 5.0);
mlDetection.addMeasurement("TestMeasurement2", 10.0);
mlCell.addMeasurement("TestMeasurement3", 15.0);
mlCell.addMeasurement("TestMeasurement4", 20.0);
// Export to GeoJSON
PathIO.exportObjectsAsGeoJSON(bos, objs, options);
// Import from GeoJSON
List<PathObject> objsBack = new ArrayList<>(PathIO.readObjectsFromGeoJSON(new ByteArrayInputStream(bos.toByteArray())));
assertEquals(objs.size(), objsBack.size());
// Array to count number of each PathObject type
int[] countCheck = new int[] { 0, 0, 0, 0, 0 };
for (PathObject po : objsBack) {
if (po == null)
continue;
// Test whether po has a ROI
assertTrue(po.hasROI());
if (po.isTile()) {
assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN));
assertSameROIs(po.getROI(), roiTile);
assertFalse(po.hasMeasurements());
countCheck[0]++;
} else if (po.isCell()) {
assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN));
assertSameROIs(po.getROI(), roiCell1);
assertSameROIs(((PathCellObject) po).getNucleusROI(), roiCell2);
if (keepMeasurements) {
assertTrue(po.hasMeasurements());
assertSameMeasurements(po.getMeasurementList(), myPCO.getMeasurementList());
} else
assertFalse(po.hasMeasurements());
countCheck[1]++;
} else if (po.isDetection()) {
assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK));
assertSameROIs(po.getROI(), roiDetection);
if (keepMeasurements) {
assertTrue(po.hasMeasurements());
assertSameMeasurements(po.getMeasurementList(), myPDO.getMeasurementList());
} else
assertFalse(po.hasMeasurements());
countCheck[2]++;
} else if (po.isAnnotation()) {
assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK));
assertSameROIs(po.getROI(), roiAnnotation);
assertFalse(po.hasMeasurements());
countCheck[3]++;
} else if (po.isTMACore()) {
assertFalse(po.hasMeasurements());
assertSameROIs(po.getROI(), myTMA.getROI());
countCheck[4]++;
}
}
assertArrayEquals(countCheck, new int[] { 1, 1, 1, 1, 1 });
}
use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.
the class TestROIs method checkROIMeasurements.
static void checkROIMeasurements(ROI roi, double pixelWidth, double pixelHeight, double delta) {
if (roi.isPoint()) {
checkROIPoints(roi);
return;
}
ROI scaledROI = roi.scale(pixelWidth, pixelHeight);
Geometry geometry = getGeometry(roi, pixelWidth, pixelHeight);
if (roi instanceof EllipseROI)
delta = roi.getArea() * delta;
if (roi.isArea()) {
ClosedShapeStatistics stats = new ClosedShapeStatistics(roi.getShape(), pixelWidth, pixelHeight);
double area = roi.getScaledArea(pixelWidth, pixelHeight);
assertEquals(area, stats.getArea(), delta);
assertEquals(area, scaledROI.getArea(), delta);
assertEquals(area, geometry.getArea(), delta);
}
if (roi.isLine()) {
double length = roi.getScaledLength(pixelWidth, pixelHeight);
assertEquals(length, scaledROI.getLength(), delta);
assertEquals(length, geometry.getLength(), delta);
}
}
use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.
the class TestROIs method roiSerialization.
@Test
public void roiSerialization() {
double tol = 0.0;
// Test serialization
LineROI roi = new LineROI(100, 200, 300, 400);
LineROI roi2 = (LineROI) objectFromBytes(objectToBytes(roi));
testEqualBounds(roi, roi2, tol);
testEqualLines(roi, roi2, tol);
assertEquals(0, DefaultROIComparator.getInstance().compare(roi, roi2));
RectangleROI rect = new RectangleROI(100, 200, 300, 400, ImagePlane.getPlaneWithChannel(0, 1, 2));
ROI rect2 = (ROI) objectFromBytes(objectToBytes(rect));
testEqualBounds(rect, rect2, tol);
testEqualPolygonPoints(rect, rect2, tol);
assertEquals(0, DefaultROIComparator.getInstance().compare(rect, rect2));
EllipseROI ellipse = new EllipseROI(100, 200, 300, 400, ImagePlane.getPlaneWithChannel(0, 1, 2));
ROI ellipse2 = (ROI) objectFromBytes(objectToBytes(ellipse));
testEqualBounds(ellipse, ellipse2, tol);
testEqualPolygonPoints(ellipse, ellipse2, tol);
assertEquals(0, DefaultROIComparator.getInstance().compare(ellipse, ellipse2));
PolygonROI poly = new PolygonROI(new float[] { 1.0f, 2.5f, 5.0f }, new float[] { 10.0f, 11.0f, 12.0f }, ImagePlane.getPlaneWithChannel(0, 1, 2));
ROI poly2 = (ROI) objectFromBytes(objectToBytes(poly));
testEqualBounds(poly, poly2, tol);
testEqualPolygonPoints(poly, poly2, tol);
assertEquals(0, DefaultROIComparator.getInstance().compare(poly, poly2));
PolylineROI polyline = new PolylineROI(new float[] { 1.0f, 2.5f, 5.0f }, new float[] { 10.0f, 11.0f, 12.0f }, ImagePlane.getPlaneWithChannel(0, 1, 2));
ROI polyline2 = (ROI) objectFromBytes(objectToBytes(poly));
testEqualBounds(polyline, polyline2, tol);
testEqualPolygonPoints(polyline, polyline2, tol);
assertEquals(0, DefaultROIComparator.getInstance().compare(poly, poly2));
// Test polygon construction from points
PolygonROI poly3 = new PolygonROI(poly.getAllPoints(), ImagePlane.getPlaneWithChannel(0, 1, 2));
testEqualBounds(poly, poly3, tol);
testEqualPolygonPoints(poly, poly3, tol);
assertEquals(0, DefaultROIComparator.getInstance().compare(poly, poly3));
}
use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.
the class AbstractPathROITool method createNewAnnotation.
/**
* Create a new annotation & set it in the current viewer.
* @param e
* @param x
* @param y
* @return
*/
PathObject createNewAnnotation(MouseEvent e, double x, double y) {
var viewer = getViewer();
var currentObject = viewer.getSelectedObject();
var editor = viewer.getROIEditor();
if (currentObject != null && currentObject.getParent() == null && currentObject.getROI() == editor.getROI() && (editor.isTranslating() || editor.hasActiveHandle())) {
logger.warn("Creating a new annotation before a previous one was complete - {} will be discarded!", currentObject);
}
logger.trace("Creating new annotation at ({}, {}", x, y);
PathObjectHierarchy hierarchy = viewer.getHierarchy();
if (hierarchy == null) {
logger.warn("Cannot create new annotation - no hierarchy available!");
return null;
}
ROI roi = createNewROI(e, x, y, viewer.getImagePlane());
if (roi == null)
return null;
PathObject pathObject = PathObjects.createAnnotationObject(roi, PathPrefs.autoSetAnnotationClassProperty().get());
var selectionModel = hierarchy.getSelectionModel();
if (PathPrefs.selectionModeProperty().get() && !selectionModel.noSelection())
viewer.setSelectedObject(pathObject, true);
else
viewer.setSelectedObject(pathObject);
return pathObject;
}
use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.
the class AbstractPathROITool method commitObjectToHierarchy.
/**
* When drawing an object is complete, add it to the hierarchy - or whatever else is required.
*
* @param e
* @param pathObject
*/
void commitObjectToHierarchy(MouseEvent e, PathObject pathObject) {
if (pathObject == null)
return;
var viewer = getViewer();
PathObjectHierarchy hierarchy = viewer.getHierarchy();
var currentROI = pathObject.getROI();
// If we are in selection mode, try to get objects to select
if (PathPrefs.selectionModeProperty().get()) {
var pathClass = PathPrefs.autoSetAnnotationClassProperty().get();
var toSelect = hierarchy.getObjectsForROI(null, currentROI);
if (!toSelect.isEmpty() && pathClass != null) {
boolean retainIntensityClass = !(PathClassTools.isPositiveOrGradedIntensityClass(pathClass) || PathClassTools.isNegativeClass(pathClass));
var reclassified = toSelect.stream().filter(p -> p.getPathClass() != pathClass).map(p -> new Reclassifier(p, pathClass, retainIntensityClass)).filter(r -> r.apply()).map(r -> r.getPathObject()).collect(Collectors.toList());
if (!reclassified.isEmpty()) {
hierarchy.fireObjectClassificationsChangedEvent(this, reclassified);
}
}
if (pathObject.getParent() != null)
hierarchy.removeObject(pathObject, true);
// viewer.getHierarchy().fireHierarchyChangedEvent(this);
if (toSelect.isEmpty())
viewer.setSelectedObject(null);
else if (e.isShiftDown()) {
hierarchy.getSelectionModel().deselectObject(pathObject);
hierarchy.getSelectionModel().selectObjects(toSelect);
} else
hierarchy.getSelectionModel().setSelectedObjects(toSelect, null);
} else {
if (!requestParentClipping(e)) {
if (currentROI.isEmpty()) {
pathObject = null;
} else
// Ensure object is within the hierarchy
hierarchy.addPathObject(pathObject);
} else {
ROI roiNew = refineROIByParent(pathObject.getROI());
if (roiNew.isEmpty()) {
hierarchy.removeObject(pathObject, true);
pathObject = null;
} else {
((PathAnnotationObject) pathObject).setROI(roiNew);
hierarchy.addPathObjectBelowParent(getCurrentParent(), pathObject, true);
}
}
if (pathObject != null)
viewer.setSelectedObject(pathObject);
else
viewer.getHierarchy().getSelectionModel().clearSelection();
}
var editor = viewer.getROIEditor();
editor.ensureHandlesUpdated();
editor.resetActiveHandle();
if (preferReturnToMove()) {
var qupath = QuPathGUI.getInstance();
if (qupath != null)
qupath.setSelectedTool(PathTools.MOVE);
}
}
Aggregations