Problem with analyze particle in new versions 1.53f (error in excluding particles touching edges)

I noticed that some particles that are not touching edges of ROI are excluded in the results from the Imagej when I did “run(“Analyze Particles…”, “size=2-Infinity display exclude clear add”)”. I tried latest daily build as well as version1.53f and got the same problem. However, when I switched back to 1.50i, the problem went away.

Please provide a test macro that reproduces this problem. The following macro finds 45 particles with both 1.53f and 1.50i.

run("Blobs (25K)");
setAutoThreshold("Default");
run("Analyze Particles...", "size=2 show=Overlay display exclude clear");

Screenshot

1 Like

Hi Wayne,

Thank you for your quick reply. I tested your macro with version 1.50i and 1.53f and got the same results. I suspect that this is problem is image and ROI specific. Here is an example: I have a segmented image with quite complex ROI . I then do "run(“Analyze Particles…”, “size=2 show=Overlay display exclude clear”); "

For version 1.53f:

Some particles (white) within ROI are not correctly recognized and are excluded.

For version 1.50i, I don’t have this problem.

I have uploaded the image with ROI as overlay for your reference.

test.tif (6.7 MB)

Thanks again for your help!

Jincheng

This particle analyzer regression is fixed in the ImageJ 1.53g22 daily. The problem occurs when using the “Exclude on edges” option and a composite selection.

1 Like

Hi Wayne,

Thank you very much for the quick response and the fix.

I do have a request for adding an option to the particle analyzer: generating composite ROI for particles. You did this in early 2019 with 1.52k version, which generated composite ROI for particles, instead of outline for particles, as the default option. Although a very useful feature, that change caused problems with compatibility with existing Imagej macros based on assumption of particle outline ROIs and you have reverted this back to generating the particle outline as ROI in version 1.52n.

However, getting composite ROI (i.e. including the holes inside the particles) for particles is a very useful feature. For example, when I do ASTM D3849 primary particle size distribution analysis of fractal nano particles, I need perimeter lengths of both outline of particles and also lengths of internal perimeters of holes. For particle analysis, I also often need to evaluate average or median grey level of the particles and composite ROI is needed in this case for particles with internal holes. To generate composite ROIs from the particle analyzer, I have been using a macro that selects each individual particle from count masks generated from the particle analyzer, then generates ROI for each particle. This works, but is quite slow for analyzing thousands of particles. For minimizing compatibility with old macros, my suggestion is that the default ROIs from particle analyzer are still kept as particle outlines, but could you add an option for particle analyzer (similar to exclude particles touching edges of ROI) that allows user to switch explicitly to the composite ROIs? I am sure many users would appreciate this new feature, based on the forum discussions over the years.

Thank you again for your help!

Jincheng

Could you post this macro? There may be a way to speed it up. It would also be helpful to have an example image with thousands of particles.

Hi Wayne,

Thank you again for your help! Here is the macro that I used to create ROIs for particles with internal holes:


////////////////////////////////////////////////////////////////////////////////////////////////
function createROIwHoles(imgID) {		
	// imgID is a segmented binary file of particles with internal holes
	// use a "counter masks" image created by analyze particles for selecting individual particles
	// As generating composite ROIs takes time, seperating ROIs with holes first saves time.

	close("*Holes*");
	run("Clear Results");
	selectImage(imgID);
	run("Select None");
	run("Duplicate...", "title=xxHoles");
	holeID = getImageID();
	selectImage(holeID);
	run("Select None");
	roiManager("deselect");
	roiManager("measure");
	//find ROIs withinternal holes
	roiHoles = newArray(0);
	roiNoHoles = newArray(0); 
	nPt = roiManager("count");
	for (i=0; i<nPt;i++) {
		if (getResult("Min", i) == 0)  	roiHoles = Array.concat(roiHoles,i);
		else 							roiNoHoles = Array.concat(roiNoHoles,i);
	}
	
	n= roiNoHoles.length;
    if (n > 0) {
      		selectImage(holeID);
      		roiManager("deselect");
      		if (n > 1) {
      			roiManager("Select", roiNoHoles); 
	        	roiManager("Combine");
	        } else {
	        	roiManager("Select", roiNoHoles[0]);
      		}
      		run("Clear", "slice");
      		roiManager("deselect");
   	}
   	nPt2 = roiHoles.length;
    if (nPt2 > 0) {
      		selectImage(holeID);
      		roiManager("deselect");
      		if (nPt2 > 1) {
      			roiManager("Select", roiHoles); 
	        	roiManager("Combine");
	        } else {
	        	roiManager("Select", roiHoles[0]);
      		}
      		roiManager("Delete");
   	}
   	
	selectImage(holeID);	
	run("Select None");	
     //run("Set Measurements...", "area mean standard modal bounding fit redirect=None decimal=3");
    run("Analyze Particles...", "size=" +areaMin+ "-Infinity pixel show=[Count Masks]" );
    binID=getImageID();

	batchMode=is("Batch Mode");
	if (!batchMode)	setBatchMode(true);
	
	//create a copy of image binID in batch mode, so any changes to the image will not be displayed
	selectImage(binID);		
	run("Select None");
	run("Duplicate...", "title=xxCountMask");  
	for (i=0; i<nPt2; i++) {
		selectImage("xxCountMask");		
		run("Select None");
		setThreshold(i+0.6,i+1.4);
		run("Create Selection");
		roiManager("add");
	}
	close("xxCountMask");
	selectImage(binID);
	close();
	close("xxHoles");
	if (!batchMode)	setBatchMode("exit and display");
	
}

For your reference, I have also uploaded an image with over 4000 particles.

ParticleImage.tif (4.7 MB)

Hi Wayne:

I forgot to mention that the function createROIwHoles(imgID) that I wrote used a global variable areaMin for the particle analyzer, which should be put as an input variable of the function createROIwHoles as createROIwHoles(imgID, areaMin), if someone uses this function without declaring and setting areaMin as a global variable first.

Jincheng

The particle analyzer in the ImageJ 1.53g31 daily build adds a “Composite ROIs” option which should be much faster than your macro.

Hi Wayne,

Thank you very much! This should really help speeding up the particle analyses. I will test the new option late today.

Jincheng

Hi Wayne,

I tested the version 1.53g31 and it worked great in generating the composite ROIs for particles with internal holes when I choose the option of “Composite ROI”! This is exactly what I needed.

However, there is no differences in the perimeter values in the results table when I choose the option of “Composite ROI”. For the “composite ROI” option, it appears that the perimeter value listed in the result table is still the perimeter of the outline of the particles, and the perimeters of the internal holes are not included. In order to get the total perimeter length including the internal holes, it appears that I have to convert the overlay of the particle back to ROI, then do “measure”. (I tried to do “measure” directly from the ROI right after particle analyzer, it did not give the total perimeter length.) It would be better to avoid this extra step. Is that possible for you to change the perimeter output in the result table to the total perimeter length, when the “Composite ROI” option is selected?

Thanks!

Jincheng

Hi Wayne,

I just took another look at the results. It appears that only overlays of the particles are composite, the ROIs added to the ROI managers only contain the outlines of the particles. This appears to be the reason why I need to convert overlay to ROI to get the total perimeter length. Could you also add the composite ROIs to the ROI manager for the particle analyzer? This should make using composite ROIs a bit easier.

Thanks!

Jincheng

Hi Wayne,

I also checked the original issue of the "exclude"ing particle touching on edge option for the version1.53g31. Although this version does not have the problem of excluding some particles within ROI, it DOES NOT actually exclude particles touching the edge of ROI. However, the version 1.50i works as expected: excluded the particles touching ROI. Here is an example:

For your reference, I uploaded the original image with the ROI (as overlay).
ParticleROIEdgeTest.tif (6.6 MB)

With the ImageJ 1.53g34 daily build, the total perimeter length is calculated when the “Composite ROIs” option is selected and composite ROIs are now added to the ROI Manager.

Wayne, thank you very much for your quick response! The composite ROIs option is going to be very helpful for us.

Hi Wayne,

The “Composite ROIs” option worked well in version 1.53g34!

I also checked the original issue of the “excluding” particle touching on edge of ROI option for the version1.53g34. This version still does not exclude the particles touching a composite ROI when the “exclude” option is specified. I got the same problem as the version 1.53g31. Please see my post last night for details and an example.

Thanks!

Jincheng

The1.53g35 daily build should fix the bug with particles touching a composite ROI not being excluded.

Hi Wayne,

Thank you very much! I just downloaded the daily build 1.53g35, and got the same result as 1.50i ( a total of 263 particles using the uploaded image) when “exclude” option is specified!

However, I encountered two issues:

(1) After I upgraded to the daily build 1,53g35, I ran the particle analyzer first time with the “exclude” option checked, I got the results as if “exclude” is not checked. However, when I repeated the particle analyzer one more time, I got the expected results. I had the same issue with version 1.52v (i.e. need to run particle analyzer twice to activate the exclude option). The version 1.50i appears to be free of this problem.

(2) After close examination of the results, I found that 4 particles “touching” the ROI are not excluded: two sharing one side with the ROI, and the other two sharing two corner vertices with the ROI.

I am a little bit confused, as all other particles sharing single side with the ROI are excluded, except for particle #46 and #47. How do you define “touching”? In addition, I checked version 1.52v and only got 260 particles when using the “exclude” option. In this case, two particles sharing one side with the ROI (#46, #47) are excluded, but two particles (#35, #61) sharing two vertices with the ROI are retained. It looks like that 1.52v has excluded all particles sharing one side with the ROI.

Thanks!

Jincheng

The particle analyzer in the 1.53g37 daily build should behave just like it does in 1.52v, in this case finding 260 particles. Unfortunately, the bug with some particles within the ROI in the test.tif image not being recognized has returned, but this may be a degenerate ROI.

Hi Wayne,

I also found that 1.52v had the problem with excluding some particles within ROI some times when “exclude” option is used, after I did further testing yesterday. I could not figure out under what condition and why some of the particles within ROI are excluded. This is much more dangerous than a few small particle touching edge of ROI are retained in version 1.50i. If I have to choose, I would rather use daily build 1.53g35 than 1.35g37. In automation and batch runs, excluding random particles would be dangerous and difficult to check.

I am curious what method that you use to check whether a particle is touching the edge in your Java program, when “exclude” option is specified. Also, what is the difference between 1.50i and 1.52v in the methods and logic for checking whether a particle touches the edge of ROI?

Thanks!

Jincheng