How to clear outside, whith multiple ROIs on a stack

Hi, I have managed to select multiple areas on a Stack, and roi manager now have around 3000 rois on a stack of 300 slices.
They appear beautifully with ShowAll on the stack and I am willing to Clear outside theese rois, to process further the slices,
But ClearOutside comes with “a selection required”!!!

What am I doing wrong?

So for this to work you need a selection that is all the ROIs in your manager.

One way to get the result you want is by clicking “More>>” and then “OR (Combine)” THEN click “Clear Outside”.

1 Like

hi @Imurphy

unfortunately this doesn’t work… (it makes a strange selection of only some rois (not all of them) and then Clears outside ONLY that areas for ALL slices

Something tells me that what i want can only be achieved with macros, like for each slice, find rois that have the slice number and select them clear outside on that slice and then proceed to the next one …till the end…

but i have no idea about macros.
thanks for your answer though!

something like this for instance

Oh sorry, I read too quickly and missed that you were working on a stack.

So what you want is to be able to do is go to each slice of your stack, select the ROIs that belong to that slice and clear outside of them? If that’s right then yes it will be a lot easier with a macro.

Edit:

Made a slightly messy macro that could be a starting point for this. I needed a sample that would demonstrate well so used the Tracks for Trackmate dataset but switched frames for slices. It’s much easier to collect the number of ROIs per slice when using Analyze Particles rather than starting at the point of already having the ROIs in the manager.

// Using sample image for demonstration - switching frames to slices
run("Tracks for TrackMate (807K)");
run("Properties...", "channels=1 slices=50 frames=1 unit=pixel pixel_width=1.0000 pixel_height=1.0000 voxel_depth=1.0000 frame=[1 sec]");
run("Gaussian Blur...", "sigma=1 stack");
setAutoThreshold("Otsu dark");

getDimensions(width, height, channels, slices, frames); // get number of slices in stack

nROIs = newArray(); // create array to store number of ROIs per slice

// Loop through slices, analyze particles per slice and storing how many ROIs are found on each slice
for (i = 1; i <= slices; i++){
	Stack.setSlice(i);
	run("Clear Results");
	run("Analyze Particles...", "size=0-Infinity exclude add slice");
	nROIs = Array.concat(nROIs, nResults);
}

counter = 0;

// Loop through slices, select ROIs per slice and clear outside them
for (j = 0; j < slices; j++){
	Stack.setSlice(j);
	current = nROIs[j];
	print("Number of ROIs on current slice is " + current);

	if (current == 0){
		continue;
	}

	if (current == 1){
		roiManager("Select", counter);
	}

	if (current > 1){
		array = newArray(current);
		for (a = 0; a < current; a++){
			array[a] = counter+a;
		}
		roiManager("Select", array);
		roiManager("Combine");
	}
		
	run("Clear Outside", "slice");
	counter = counter + current;
}
2 Likes

yes …so it seems…

know i have to learn “macro” syntax :scream:

1 Like

If you have all the ROI in the ROI manager, then this should be quite easy using a macro.
Each ROI ought to be tied to its specific slice. (To verify, open the ROI manager (Analyze => tools => ROI manger) and click a few different ROI. This should bring you to the corresponding slice)

Then it is just a matter of looping over all ROI and clearing outside for each.

In pseudo code:
for (all ROI)
select(roinumber)
clear outside

And in macro code:


for(i=0;i<roiManager("count");i++){
   roiManager("Select",i);
   run("Clear Outside","Slice");
}

Word of warning: this only works if you have a single ROI per slice (since it first clears everything outside one ROI and then clears everything outside the next ROI).

Also, whenever you play around with macros that alter your images, it is usually a good idea to work on copies of your images lest you accidentally destroy your data.

hi @HenrikPersson

thanks …
Yes I learned the WORK on DUPLICATES …with the hard way … (the last weeks that i am using FIJI!!!

Your code will work …but first …i have to do something like… combine all rois of each slice in ONE new roi, add it in roi manager, delete the “separate rois of each slice” that are not necessary any more, and then Run the code you just posted…!

For ALL slices
find ROIs in format 00i--* (i is the slice )
Combine them in ONE ROI and ADD it on the list then DELETE all 00i-***-***

can you help with this syntax maybe?

never mind not necessary any more
I have manage to gain one ROI per slice running a macro that i Found (cant remember where to be honest ) in a binarized Stack …so it returned with ONE roi per Slice

name=getTitle; 
run("Threshold..."); 
msga = "Set threshold values then click OK "; 
waitForUser(msga); 
run("Analyze Particles...", "size=150-infinity show=Masks stack"); 
rename("Mask"); 
n = getSliceNumber(); 
while (getSliceNumber()<nSlices){ 
run("Create Selection"); 
type = selectionType(); 
if (type==-1) 
run("Next Slice [>]"); 
else 
roiManager("Add"); 
run("Next Slice [>]");} 
run("Create Selection"); 
type = selectionType(); 
if (type==-1) 
run("Next Slice [>]"); 
else 
roiManager("Add"); 
selectWindow("Mask"); 
close(); 
selectWindow(name); 
resetThreshold(); 
msga = "Scroll through ROI manager to check segmentation of enamel. Click OK to see results.";
waitForUser(msga); 
roiManager("Deselect"); 
run("Set Measurements...", "area mean standard redirect=None decimal=1");
roiManager("Measure");
un("Analyze Particles...", "size=150-infinity show=Masks stack");

should become something like

un("Analyze Particles...", "size=.001-infinity show=Masks stack");

to work properly

Though After run @HenrikPersson 's macro
ALL slice become black !! (maybe ROis are open and not closed regions.!!!) Eventhough they seem to be closed

if I do it manually (Each slice) it does it correctly!! maybe something missing from henrik’s code…
Anyway I shall thank henrik, that even manually i came to solution !

well problem solved …

I totally have no idea about macros (or at least how to syntax)
So most probably henrik meant

for(i=0;i<roiManager("count");i++)

were in COUNT i should put my rois maximum number (equal to slices in my case… )
so now that i changed it like

for(i=0;i<301;i++){
   roiManager("Select",i);
   run("Clear Outside","Slice")
}

and run it …Voilla!! outside was cleared in a fraction of a second …!

Thanks so much @HenrikPersson and also @lmurphy

2 Likes

Glad you managed to solve it @MHD!
Thank you for sharing your solution for others to find as opposed to “never mind, solved it” (which seems to be most threads when I need code help :slight_smile: ).

2 Likes