Add support for OME XML shapes by Rylern · Pull Request #1848 · qupath/qupath
You can use Fiji to get some view of the OME-XML. I see the ROIs are Mask objects, and currently we only return these as rectangles.
There is some information at https://forum.image.sc/t/prepping-and-including-roi-masks/48750 but I'm struggling to understand how this information is supposed to be parsed.
Still, I hacked together this as an alternative to the current createMask function::
private static ROI convertMask(Mask mask) { logger.debug("Converting mask {} to QuPath rectangle ROI", mask); // I don't know why width and height are doubles... // since we don't have the scale info here, I assume square pixels & try to figure out // the required transform var binData = mask.getBinData(); long nPixels = binData.getLength().getValue(); int width = (int)Math.sqrt(Math.round(nPixels * (mask.getWidth() / mask.getHeight()))); int height = (int)(nPixels / width); if (((long)width * height) != nPixels) { logger.warn("Couldn't figure out dimensions: {}x{} != {} pixels", width, height, nPixels); return null; } // Create an image we can pass to ContourTracing var array = binData.getBase64Binary(); var simpleImage = SimpleImages.createFloatImage(width, height); for (int i = 0; i < nPixels; i++) { if (array[i] != 0) { simpleImage.setValue(i % width, i / width, 1.0f); } } // Create a request we can use to calibrate the ROI // We're assuming x and y are integers and that there is no other transform! var request = RegionRequest.createInstance("", 1.0, mask.getX().intValue(), mask.getY().intValue(), simpleImage.getWidth(), simpleImage.getHeight(), ImagePlane.getPlane(mask.getTheZ().getValue(), mask.getTheT().getValue())); return ContourTracing.createTracedROI(simpleImage, 1, 1, request); }
It gives much more plausible ROIs for the sample image:
There's also an interesting script that shows conversion in the opposite direction at https://github.com/glencoesoftware/ome-omero-roitool/blob/7b3896f6f6f3c168f3610a4a416ccf46df1aa278/src/dist/QuPath.scripts/OME_XML_export.groovy#L243
And a potentially-useful sample that shows more contortions are likely to be needed to figure out how to ensure that we only get annotations for the current series, and not for all ROIs in the image file:
https://github.com/ome/bioformats/blob/c997de185fc71eef191a1c9d82c35990bbd042c9/components/formats-gpl/utils/PrintROIs.java#L52
I've converted this to a draft PR as we probably shouldn't merge it currently.
One potential issue I can't check is that we might end up with this issue again, since I'm not sure how OMERO/the OME Model handles weird, self-intersecting polygons #1674
I think it's worth considering if you find any way to test it, but it may also be obscure enough not to be problematic and I don't think it should be a blocker... since we can't guarantee lossless conversion of ROI types anyway.
