use of qupath.lib.roi.EllipseROI in project qupath by qupath.
the class IconFactory method createROIIcon.
/**
* Create an icon depicting a ROI.
* @param roi the region of interest
* @param width the preferred icon width
* @param height the preferred icon height
* @param color the icon (line) color
* @return a node that may be used as an icon resembling the shape of the ROI
*/
public static Node createROIIcon(ROI roi, int width, int height, Color color) {
double scale = Math.min(width / roi.getBoundsWidth(), height / roi.getBoundsHeight());
if (roi instanceof RectangleROI) {
Rectangle rect = new Rectangle(0, 0, roi.getBoundsWidth() * scale, roi.getBoundsHeight() * scale);
rect.setStroke(color);
rect.setFill(null);
return rect;
} else if (roi instanceof EllipseROI) {
double w = roi.getBoundsWidth() * scale;
double h = roi.getBoundsHeight() * scale;
Ellipse ellipse = new Ellipse(w / 2, height / 2, w / 2, h / 2);
ellipse.setStroke(color);
ellipse.setFill(null);
return ellipse;
} else if (roi instanceof LineROI) {
LineROI l = (LineROI) roi;
double xMin = Math.min(l.getX1(), l.getX2());
double yMin = Math.min(l.getY1(), l.getY2());
Line line = new Line((l.getX1() - xMin) * scale, (l.getY1() - yMin) * scale, (l.getX2() - xMin) * scale, (l.getY2() - yMin) * scale);
line.setStroke(color);
line.setFill(null);
return line;
} else if (roi.isPoint()) {
// Just show generic points
Node node = IconFactory.createNode(Math.min(width, height), Math.min(width, height), IconFactory.PathIcons.POINTS_TOOL);
if (node instanceof Glyph) {
var glyph = (Glyph) node;
glyph.textFillProperty().unbind();
glyph.setColor(color);
}
return node;
} else {
var path = pathCache.getOrDefault(roi, null);
if (path == null) {
var shape = roi.isArea() ? RoiTools.getArea(roi) : RoiTools.getShape(roi);
if (shape != null) {
var transform = new AffineTransform();
transform.translate(-roi.getBoundsX(), -roi.getBoundsY());
transform.scale(scale, scale);
PathIterator iterator = shape.getPathIterator(transform, Math.max(0.5, 1.0 / scale));
path = createShapeIcon(iterator, color);
pathCache.put(roi, path);
}
} else {
path = new Path(path.getElements());
path.setStroke(color);
}
if (path != null)
return path;
}
logger.warn("Unable to create icon for ROI: {}", roi);
return null;
}
use of qupath.lib.roi.EllipseROI in project qupath by qupath.
the class IJTools method convertToIJRoi.
/**
* Convert a QuPath ROI to an ImageJ Roi.
* @param <T>
* @param pathROI
* @param xOrigin x-origin indicating relationship of ImagePlus to the original image, as stored in ImageJ Calibration object
* @param yOrigin y-origin indicating relationship of ImagePlus to the original image, as stored in ImageJ Calibration object
* @param downsampleFactor downsample factor at which the ImagePlus was extracted from the full-resolution image
* @return
*/
public static <T extends PathImage<ImagePlus>> Roi convertToIJRoi(ROI pathROI, double xOrigin, double yOrigin, double downsampleFactor) {
if (pathROI instanceof PolygonROI)
return ROIConverterIJ.convertToPolygonROI((PolygonROI) pathROI, xOrigin, yOrigin, downsampleFactor);
if (pathROI instanceof RectangleROI)
return ROIConverterIJ.getRectangleROI((RectangleROI) pathROI, xOrigin, yOrigin, downsampleFactor);
if (pathROI instanceof EllipseROI)
return ROIConverterIJ.convertToOvalROI((EllipseROI) pathROI, xOrigin, yOrigin, downsampleFactor);
if (pathROI instanceof LineROI)
return ROIConverterIJ.convertToLineROI((LineROI) pathROI, xOrigin, yOrigin, downsampleFactor);
if (pathROI instanceof PolylineROI)
return ROIConverterIJ.convertToPolygonROI((PolylineROI) pathROI, xOrigin, yOrigin, downsampleFactor);
if (pathROI instanceof PointsROI)
return ROIConverterIJ.convertToPointROI((PointsROI) pathROI, xOrigin, yOrigin, downsampleFactor);
// If we have any other kind of shape, create a general shape roi
if (pathROI != null && pathROI.isArea()) {
// TODO: Deal with non-AWT area ROIs!
Shape shape = RoiTools.getArea(pathROI);
// "scaleX", "shearY", "shearX", "scaleY", "translateX", "translateY"
shape = new AffineTransform(1.0 / downsampleFactor, 0, 0, 1.0 / downsampleFactor, xOrigin, yOrigin).createTransformedShape(shape);
return ROIConverterIJ.setIJRoiProperties(new ShapeRoi(shape), pathROI);
}
// TODO: Integrate ROI not supported exception...?
return null;
}
use of qupath.lib.roi.EllipseROI in project qupath by qupath.
the class PathObjectTools method transformObject.
/**
* Create a(n optionally) transformed version of a {@link PathObject}.
* <p>
* Note: only detections (including tiles and cells) and annotations are fully supported by this method.
* Root objects are duplicated.
* TMA core objects are transformed only if the resulting transform creates an ellipse ROI, since this is
* currently the only ROI type supported for a TMA core (this behavior may change).
* Any other object types result in an {@link UnsupportedOperationException} being thrown.
*
* @param pathObject the object to transform; this will be unchanged
* @param transform optional affine transform; if {@code null}, this effectively acts to duplicate the object
* @param copyMeasurements if true, the measurement list of the new object will be populated with the measurements of pathObject
*
* @return a duplicate of pathObject, with affine transform applied to the object's ROI(s) if required
*/
public static PathObject transformObject(PathObject pathObject, AffineTransform transform, boolean copyMeasurements) {
ROI roi = maybeTransformROI(pathObject.getROI(), transform);
PathClass pathClass = pathObject.getPathClass();
PathObject newObject;
if (pathObject instanceof PathCellObject) {
ROI roiNucleus = maybeTransformROI(((PathCellObject) pathObject).getNucleusROI(), transform);
newObject = PathObjects.createCellObject(roi, roiNucleus, pathClass, null);
} else if (pathObject instanceof PathTileObject) {
newObject = PathObjects.createTileObject(roi, pathClass, null);
} else if (pathObject instanceof PathDetectionObject) {
newObject = PathObjects.createDetectionObject(roi, pathClass, null);
} else if (pathObject instanceof PathAnnotationObject) {
newObject = PathObjects.createAnnotationObject(roi, pathClass, null);
} else if (pathObject instanceof PathRootObject) {
newObject = new PathRootObject();
} else if (pathObject instanceof TMACoreObject && roi instanceof EllipseROI) {
var core = (TMACoreObject) pathObject;
newObject = PathObjects.createTMACoreObject(roi.getBoundsX(), roi.getBoundsY(), roi.getBoundsWidth(), roi.getBoundsHeight(), core.isMissing());
} else
throw new UnsupportedOperationException("Unable to transform object " + pathObject);
if (copyMeasurements && !pathObject.getMeasurementList().isEmpty()) {
MeasurementList measurements = pathObject.getMeasurementList();
for (int i = 0; i < measurements.size(); i++) {
String name = measurements.getMeasurementName(i);
double value = measurements.getMeasurementValue(i);
newObject.getMeasurementList().addMeasurement(name, value);
}
newObject.getMeasurementList().close();
}
return newObject;
}
Aggregations