Scripting: accessing annotations from several different images

已查看 172 次
跳至第一个未读帖子

Henrik Marklund

未读,
2018年7月2日 20:23:042018/7/2
收件人 QuPath users
Hi! Thanks for a fantastic software. I am a new user and new to this forum. Hopefully you guys can help me out.

The problem
I have an image project with 2 images. Using the script editor, I know how to manipulate annotations on the image I am currently viewing in the GUI. However, I want to be able to access the other image in my project (from my script script) so that I can use info about annotations in that image, to manipulate annotations in my other image.

What I have tried
I've tried to the following function to return an imageData. Even though I have checked that the imageDataPath is correct, it returns null. The path points to a .svs file.

imageData = QPEx.loadImageData(imageDataPath, false)


I've also tried building a server. But I can't seem to create an ImageData using this server:
project = getProject()
imageList = project.getImageList()
server
= project.buildServer(imageList[0])


Ideally, I'd like to be able to "toggle" between the images in my code, using the name of the image.

Thanks a lot in advance,
Henrik

micros...@gmail.com

未读,
2018年7月2日 21:42:392018/7/2
收件人 QuPath users
Hmm, this is a little beyond what I have done for most of my scripts, but perhaps if you are trying to store it you could try using "getImageData" instead?  I am pretty sure I saw a post here or on GitHub about having multiple images open at the same time (right click in viewer, Multiview)  and (I think) accessing them through scripts.  As long as both images are open in Multiview, it might make the whole thing easier... though I have not tested it.

Ah, actually it was a while ago (Jan 2017) on the Gitter site. There was a whole discussion where someone was using multiple viewers in a project.  Not sure if it will be of any use or not...
One part in particular shows accessing image data from multiple viewers:

def qupath = getQuPath()
def viewers = qupath.getViewers()
def randomViewer = viewers[(int)(Math.random()*viewers.size())]
setBatchImageData
(randomViewer.getImageData())


Hopefully Pete will have a more useful answer!  Maybe access to two different images with similar enough of annotations would allow an alternative to overlaying two images, with the appropriate transforms.

Pete

未读,
2018年7月3日 04:01:342018/7/3
收件人 QuPath users
Ha, I had absolutely no memory whatsoever of creating a loadImageData method for scripting.  Intriguing... if only there were also the other helper methods to make it more useful.

Anyhow, this should do what you need (and a little extra):

import qupath.lib.gui.QuPathGUI

// Get a list of all images in the project, except the current one
def project = getProject()
def entries = project.getImageList()
entries
.remove(getProjectEntry())

// Get path to a .qpdata file
def file = QuPathGUI.getImageDataFile(project, entries[0])

// Read the data
def imageData = loadImageData(file.getAbsolutePath(), false)
print imageData

The key thing is that you need the path to the .qpdata file, not to the image.  The easiest way to get that is to call a static method in the GUI class... which is admittedly a little strange.

Anyhow, while forgetting the existence of loadImageData the other way to do it more directly is this:

import java.awt.Image.BufferedImage
import qupath.lib.io.PathIO

imageData
= PathIO.readImageData(file, null, null, BufferedImage.class)

The nulls are a bit strange.  If you care why they exist, this is the place to look.  Basically,  if you pass only the .qpdata file path then QuPath will read the image path from that... but the image path is also stored in the project and might be updated there (because it's comparatively easy to update the paths in the project, since it's just text/JSON - and necessary if images are moved).  So the ability to use a pre-existing ImageServer object means that the ImageData can be created without depending on the .qpdata file containing the right path.

One last thing: if you don't care about the pixels at all at this point, only annotations, you can use

import qupath.lib.io.PathIO

hierarchy
= PathIO.readHierarchy(file)

This way you don't need to bother with the image server at all.  It should also be much faster, because constructing the server is the slowest part... although that may be less important in a project with two images.
回复全部
回复作者
转发
0 个新帖子