fiji / microscope-image-quality

TensorFlow-based classifier for microscope image focus quality.
https://imagej.net/Microscope_Focus_Quality
Apache License 2.0
17 stars 2 forks source link

Efficiency #10

Open sklu1 opened 1 week ago

sklu1 commented 1 week ago

Hello,

I'm relatively new to ImageJ macros and I'm trying to analyze the image quality of a couple thousand z-stack images to select the most in-focus image. I noticed that it re-initializes and loads a new saved model for each image, increasing the processing time. I was wondering if there was a way to reconfigure the java files so that I can iterate through the images using the same model variable. What would you recommend is the easiest way to do this?

I figure I would likely have to somehow pass the program the list of files, but I don't know I can do that using what ImageJ provides me.

Thanks!

ctrueden commented 17 hours ago

@sklu1 Yes, the plugin as currently written loads the model every time. On a quick test I did just now on a 768x512 image, the timing from the log was:

Loaded microscope focus image quality model in 163ms Ran image through model in 149ms

So loading the model is slower than running it. :laughing:

Whether it's worth our time to dive into the code and refactor it to enable model reuse more easily will depend on how many images you are needing to process here. By the numbers above, if it's 1000, it'll take 5.2 minutes unoptimized or 2.48 minutes optimized. If 10 thousand, 52 minutes versus 24.8. For 100 thousand: 8.67 hours versus 4.14.

Assuming it takes us an hour or more to tune up the code, it'll only be worthwhile as we get into the tens of thousands range. Since you only have 2000 or so, just run it in a loop and wait the 10 minutes, eh? :shrug:

To run a Fiji plugin across all files in a folder, you can use the "Process Folder (ImageJ macro)" template of the Script Editor, as described here on the wiki. Then for the processFile function, you can use code like:

open(input + File.separator + file);
title=getTitle();
run("Microscope Image Focus Quality", "originalimage=" + title + " tilecountx=9 tilecounty=6 createprobabilityimage=true overlaypatches=true solidpatches=false borderwidth=4");
selectImage("Probabilities");
saveAs("Tiff", output + File.separator + file + "-probabilities.tif");
close();
close();

and maybe add a setBatchMode(true) at the beginning of the macro before the processFolder(input).

(I got the run line by using ImageJ's Macro Recorder, which is useful for quickly prototyping code from command executions.)

Happy to help if you have any questions getting it going, either here on this issue, or else on https://forum.image.sc/ in the "Usage & Issues" category with fiji tag.

ctrueden commented 17 hours ago

Taking a step back: it may also be that you don't even need to use this Fiji plugin, but rather can write Python code that calls the TensorFlow model and just consumes the model outputs directly, which are much more concise and direct, as per-patch quality values rather than rendered as an image with same resolution as the input.

What do you ultimately want to do with these quality measurements?

sklu1 commented 1 hour ago

Thanks for your response! I appreciate your help a lot!

That is true. I was considering it, but some existing code that another lab member wrote was in ImageJ macro, so I thought it would be best to just continue it in that.

My goal is to quantify the image quality of all images in a z-stack of files, select the most in focus image, and process it using Analyze Particles, and then save the most in-focus image as well as the data from analysis into a specific folder. I would do this over roughly 7000 images (288 z-stacks). The reason I have to iterate through the z-stack is because the spores/yeast cells can shift out of a single plane after a couple hours.

I saw that in the code you wrote above, that you would be saving the probability image. How would I be able to retrieve a value instead? I see in the original code that they are all dump in the log, but I couldn't seem to find a way to get the values to continue the pipeline.