Chosing binary objects from one image that have intersecion with object(s) from the second image

I have two binary images of the same size and each of them contains multiples objects. Something like:

and
I need to create a new binary image consisting only of the objects from the first image that intersect with some objects from the second image. Getting just the intersection is not enough. So my result need to look like

I cannot find any combination of operations from “Image Calculator” that would work. Is there any way this could be done by build-in functions or some plug-ins?

If not and I need to write some code then how to go about this problem? I thought about grouping positive pixels’ coordinates (from Analyze>Tools>Save XY coordinates) belonging to a single object into a list and thus getting a list of lists for each image and then comparing those between images object by object but that seems to be quite complicated and time consuming as my actual images are approx. 10 000 x 10 000px and contain thousands of objects. Is there a simple way to do this?

You can do this for example with the Particle Analyzer.

Just let the Particle Analyzer run over the mask A:
Analyze > Analyze Particles …

Add to Manager and then you measure if any of the objects A have signal from mask B.
You can then exclude any objects from mask A that have 0 signal in mask B.

Then you can run the Particle Analyzer for mask B as well.

Its relatively easy to script this. Just one trick for the ROI Manager, if you exclude objects the ROI index is changed meaning the deleted slots will not stay empty. Thus it is better to loop from the top instead of from the bottom. I can explain this better in a short script if you go this route…

Hi @mmg,

there’s probably many solutions to this. Here’s one that only relies on a simple macro (no scripting): first calculate the intersection of the two masks using the binary AND operation. Then use the obtained regions as seeds for a watershed operation where you use the first image as a mask. This gives you a labelled image where only labels > 0 should be kept, which you can do by binarising the image. Here’s an example of a macro that does this using the MorpholibJ plugin.

selectWindow("zbiorA.png");
run("8-bit");
run("Invert");
selectWindow("zbiorB.png");
run("8-bit");
run("Invert");
imageCalculator("AND create", "zbiorA.png","zbiorB.png");
run("Marker-controlled Watershed", "input=zbiorA marker=Result mask=zbiorA binary use");
setOption("BlackBackground", false);
run("Make Binary");

Not sure how fast this performs on really large images though…

Cheers
Guillaume

1 Like

The procedure you are after is called Binary Reconstruction. There is a plugin to do this in the Morphology collection. You reconstruct an image (mask) based on another (seed)

2 Likes

Edit to the macro above taking into account @gabriel 's remark:

selectWindow("zbiorA.png");
run("8-bit");
run("Invert");
selectWindow("zbiorB.png");
run("8-bit");
run("Invert");
imageCalculator("AND create", "zbiorA.png","zbiorB.png");
run("Morphological Reconstruction", "marker=[Result of zbiorA.png] mask=zbiorA.png type=[By Dilation] connectivity=4");
2 Likes

@gabriel & @guiwitz thank you very much for your help - this solution is simple and it works :slight_smile:

@schmiedc could you please elaborate on your idea? I’m not sure what you meant but it sounds interesting especially as it happens that I have intersections of just few pixels which are artifacts and it would be perfect if I could use Analysize particules… to set some kind of threshold to not include those into my final image.

Sure. But it is much less concise and more error prone than the above solutions. I would recommend to clean up the mask for example using the analyze particles using as an output another mask via Show: Mask.

Then work form there…

But anyways here is my solution as minimal example:

selectWindow("zbiorA.png");
run("8-bit");
run("Invert");
selectWindow("zbiorB.png");
run("8-bit");
run("Invert");

selectWindow("zbiorA.png");
run("Set Measurements...", "mean redirect=None decimal=3");
run("Analyze Particles...", "add");

roiCount = roiManager("count");

for (i = roiCount-1; i > 0; i--) {

	roiNum = i + 1;

	roiManager("Select", i);
	selectWindow("zbiorB.png");
	roiManager("Measure");
	getMeasure = getResult("Mean", 0);
	print("ROI " + roiNum + " has mean value of: " + getMeasure);

	// here set criterium for rejection
	if (getMeasure == 0) {

		print("Deleting ROI: " + roiNum );
		roiManager("Delete");
		
	} else {
		print("Keeping ROI: " + roiNum );
	}

	selectWindow("Results");
	run("Close");
	
}

1 Like

@schmiedc thank you for your input. On cropped images (500x500px) it worked nicely and this thresholding would come in really handy but… for the full sized image its taking hours to complete the task for just one pair of images. Could this work faster? I gave up printing to log but it haven’t helped much. I don’t feel the need to be monitoring the progress in real time and thus I was wondering whether it is obligatory for all of those “Results” windows to pop-up and all of those roi’s to be constantly modified on top of the image? Could all of those calculations be done in the background so that I would just get the resultant image and object count at the end?

Hi,

you can of course set the batchmode on. So you don’t visualize the images.

setBatchMode(true);

This should make it faster.
As far as I know within the Macro language you cannot just let the results and ROIManager run in the background. You would need to turn to a proper scripting language for that.

Unfortunately

setBatchMode(true);

was causing some strange problems to occur which seemed to be connected to it clearing ROI Manager. However

run(“Hide Overlay”);

was enough to speed things up about 10x which resulted in acceptable computational time and the thresholding works perfectly making the calculations not only faster but also more accurate that if I were to do them manually.

Thanks for your help.

1 Like