use of qupath.lib.display.ImageDisplay in project qupath by qupath.
the class ImageJMacroRunner method runMacro.
static void runMacro(final ParameterList params, final ImageData<BufferedImage> imageData, final ImageDisplay imageDisplay, final PathObject pathObject, final String macroText) {
// Don't try if interrupted
if (Thread.currentThread().isInterrupted()) {
logger.warn("Skipping macro for {} - thread interrupted", pathObject);
return;
}
PathImage<ImagePlus> pathImage;
// Extract parameters
double downsampleFactor = params.getDoubleParameterValue("downsampleFactor");
boolean sendROI = params.getBooleanParameterValue("sendROI");
boolean sendOverlay = params.getBooleanParameterValue("sendOverlay");
ROI pathROI = pathObject.getROI();
ImageDisplay imageDisplay2 = params.containsKey("useTransform") && Boolean.TRUE.equals(params.getBooleanParameterValue("useTransform")) ? imageDisplay : null;
ImageServer<BufferedImage> server = imageDisplay2 == null || imageDisplay2.availableChannels().isEmpty() ? imageData.getServer() : ChannelDisplayTransformServer.createColorTransformServer(imageData.getServer(), imageDisplay.availableChannels());
RegionRequest region = RegionRequest.createInstance(imageData.getServer().getPath(), downsampleFactor, pathROI);
// Check the size of the region to extract - abort if it is too large of if ther isn't enough RAM
try {
IJTools.isMemorySufficient(region, imageData);
} catch (Exception e1) {
Dialogs.showErrorMessage("ImageJ macro error", e1.getMessage());
return;
}
try {
if (sendOverlay)
pathImage = IJExtension.extractROIWithOverlay(server, pathObject, imageData.getHierarchy(), region, sendROI, null);
else
pathImage = IJExtension.extractROI(server, pathObject, region, sendROI);
} catch (IOException e) {
logger.error("Unable to extract image region " + region, e);
return;
}
// IJHelpers.getImageJInstance();
// ImageJ ij = IJHelpers.getImageJInstance();
// if (ij != null && WindowManager.getIDList() == null)
// ij.setVisible(false);
// Determine a sensible argument to pass
String argument;
if (pathObject instanceof TMACoreObject || !pathObject.hasROI())
argument = pathObject.getDisplayedName();
else
argument = String.format("Region (%d, %d, %d, %d)", region.getX(), region.getY(), region.getWidth(), region.getHeight());
// Check if we have an image already - if so, we need to be more cautious so we don't accidentally use it...
// boolean hasImage = WindowManager.getCurrentImage() != null;
// Actually run the macro
final ImagePlus imp = pathImage.getImage();
imp.setProperty("QuPath region", argument);
WindowManager.setTempCurrentImage(imp);
// Ensure we've requested an instance, since this also loads any required extra plugins
IJExtension.getImageJInstance();
// TODO: Pay attention to how threading should be done... I think Swing EDT ok?
try {
// SwingUtilities.invokeAndWait(() -> {
boolean cancelled = false;
ImagePlus impResult = null;
try {
IJ.redirectErrorMessages();
Interpreter interpreter = new Interpreter();
impResult = interpreter.runBatchMacro(macroText, imp);
// If we had an error, return
if (interpreter.wasError()) {
Thread.currentThread().interrupt();
return;
}
// Get the resulting image, if available
if (impResult == null)
impResult = WindowManager.getCurrentImage();
} catch (RuntimeException e) {
logger.error(e.getLocalizedMessage());
// DisplayHelpers.showErrorMessage("ImageJ macro error", e.getLocalizedMessage());
Thread.currentThread().interrupt();
cancelled = true;
} finally {
// IJ.runMacro(macroText, argument);
WindowManager.setTempCurrentImage(null);
// IJ.run("Close all");
}
if (cancelled)
return;
// Get the current image when the macro has finished - which may or may not be the same as the original
if (impResult == null)
impResult = imp;
boolean changes = false;
if (params.getBooleanParameterValue("clearObjects") && pathObject.hasChildren()) {
pathObject.clearPathObjects();
changes = true;
}
if (params.getBooleanParameterValue("getROI") && impResult.getRoi() != null) {
Roi roi = impResult.getRoi();
Calibration cal = impResult.getCalibration();
PathObject pathObjectNew = roi == null ? null : IJTools.convertToAnnotation(roi, cal.xOrigin, cal.yOrigin, downsampleFactor, region.getPlane());
if (pathObjectNew != null) {
// If necessary, trim any returned annotation
if (pathROI != null && !(pathROI instanceof RectangleROI) && pathObjectNew.isAnnotation() && RoiTools.isShapeROI(pathROI) && RoiTools.isShapeROI(pathObjectNew.getROI())) {
ROI roiNew = RoiTools.combineROIs(pathROI, pathObjectNew.getROI(), CombineOp.INTERSECT);
((PathAnnotationObject) pathObjectNew).setROI(roiNew);
}
// Only add if we have something
if (pathObjectNew.getROI() instanceof LineROI || !pathObjectNew.getROI().isEmpty()) {
pathObject.addPathObject(pathObjectNew);
// imageData.getHierarchy().addPathObject(IJHelpers.convertToPathObject(imp, imageData.getServer(), imp.getRoi(), downsampleFactor, false), true);
changes = true;
}
}
}
boolean exportAsDetection = ((String) params.getChoiceParameterValue("getOverlayAs")).equals("Detections") ? true : false;
if (params.getBooleanParameterValue("getOverlay") && impResult.getOverlay() != null) {
var overlay = impResult.getOverlay();
List<PathObject> childObjects = QuPath_Send_Overlay_to_QuPath.createObjectsFromROIs(imp, Arrays.asList(overlay.toArray()), downsampleFactor, exportAsDetection, true, region.getPlane());
if (!childObjects.isEmpty()) {
pathObject.addPathObjects(childObjects);
changes = true;
}
// for (Roi roi : impResult.getOverlay().toArray()) {
// pathObject.addPathObject(IJTools.convertToPathObject(imp, imageData.getServer(), roi, downsampleFactor, true));
// changes = true;
// }
}
if (changes) {
Platform.runLater(() -> imageData.getHierarchy().fireHierarchyChangedEvent(null));
}
// });
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Aggregations