Created
July 21, 2020 08:33
-
-
Save petebankhead/c696ffb62c5d11ebac299953f9fd6cce to your computer and use it in GitHub Desktop.
Script to transfer QuPath objects from one image to another, applying an AffineTransform to any ROIs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Script to transfer QuPath objects from one image to another, applying an AffineTransform to any ROIs. | |
* | |
* This is a based upon the script I posted on the epic forum thread https://forum.image.sc/t/interactive-image-alignment/23745/9?u=petebankhead | |
* It has been updated for QuPath v0.2.0 (and made quite a lot shorter along the way). | |
* | |
* @author Pete Bankhead | |
*/ | |
// SET ME! Define transformation matrix | |
// You can determine this using the 'Interactive image alignment' command | |
def matrix = [ | |
-0.998, -0.070, 127256.994, | |
0.070, -0.998, 72627.371 | |
] | |
// SET ME! Define image containing the original objects (must be in the current project) | |
def otherImageName = 'type your image name here' | |
// SET ME! Delete existing objects | |
def deleteExisting = true | |
// SET ME! Change this if things end up in the wrong place | |
def createInverse = true | |
// SET ME! Change this to false if you want to discard existing measurements | |
// Note that things like area might be incorrect if the transform includes rescaling | |
boolean copyMeasurements = true | |
import qupath.lib.objects.PathObject | |
import qupath.lib.objects.PathObjectTools | |
import java.awt.geom.AffineTransform | |
import static qupath.lib.gui.scripting.QPEx.* | |
if (otherImageName == null) { | |
Dialogs.showErrorNotification("Transform objects", "Please specify an image name in the script!") | |
return | |
} | |
// Get the project & the requested image name | |
def project = getProject() | |
def entry = project.getImageList().find {it.getImageName() == otherImageName} | |
if (entry == null) { | |
print 'Could not find image with name ' + otherImageName | |
return | |
} | |
def otherHierarchy = entry.readHierarchy() | |
def pathObjects = otherHierarchy.getRootObject().getChildObjects() | |
// Define the transformation matrix | |
def transform = new AffineTransform( | |
matrix[0], matrix[3], matrix[1], | |
matrix[4], matrix[2], matrix[5] | |
) | |
if (createInverse) | |
transform = transform.createInverse() | |
if (deleteExisting) | |
clearAllObjects() | |
def newObjects = [] | |
for (pathObject in pathObjects) { | |
newObjects << transformObject(pathObject, transform, copyMeasurements) | |
} | |
addObjects(newObjects) | |
print 'Done!' | |
/** | |
* Transform object, recursively transforming all child objects | |
* | |
* @param pathObject | |
* @param transform | |
* @return | |
*/ | |
PathObject transformObject(PathObject pathObject, AffineTransform transform, boolean copyMeasurements) { | |
def newObject = PathObjectTools.transformObject(pathObject, transform, copyMeasurements) | |
// Handle child objects | |
if (pathObject.hasChildren()) { | |
newObject.addPathObjects(pathObject.getChildObjects().collect({transformObject(it, transform, copyMeasurements)})) | |
} | |
return newObject | |
} |
Hi @marco1108p if you don't need the other objects, you can just remove the lines
// if (pathObject.hasChildren()) {
// newObject.addPathObjects(pathObject.getChildObjects().collect({transformObject(it, transform, copyMeasurements)}))
// }
If you need something more complicated, I'd suggest posting a question on the forum at http://forum.image.sc/tag/qupath
Many thanks Pete! This was exactly what I needed.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have used the QuPath-Transform and transform objects.groovy and works great. However, I would need to transfer only the first order objects of the hierarchy and not all the child objects (eg the objects listed in the figure without all the child objects). I have made a few attempts without success.
Many thanks!