Remove overlap and out-of-focus particles


#1

Hello everyone,

I am a very new user of ImageJ and am learning how to use ImageJ to analyze mud aggregates. My experiments aim to calculate particle size distribution of different concentrations (from 25 to 400 mg/L).

There are two main problems. First, at higher concentration (200 mg/L and above) the number of overlap increases significantly. Second, I do not know how to remove the out-of-focus particles. Below are the code and the images that we are using.

For problem 1 (overlap) we use Circularity range from 0.09-0.65 to remove overlap. This is because from statistic data we realized that this is the range of a typical aggregate in our experiment. Yet, it did not do a good job (at higher concentration).

For problem 2 (out-of-focus) I still have no idea how to deal with it. Scouring the forum, I end up with two potential solutions: 1) using “Find edges” and 2) using Trainable Weka Segmentation. Unfortunately, as a newbie I do not know how to integrate it into our code.

I think the two problems that I have are quite typical and I am afraid that I might miss some of the very fundamental knowledge/technique to deal with it.

Could anyone please help me with more information/method to solve these two problems? I hope it is not too much to ask if you could also modify the code for me?

I have to convert images to *.tiff to be able to upload them. The code runs with images in *.bmp. If you cannot access the images, please follow this link.
https://drive.google.com/drive/folders/0B7-fnibR1d38al8zLVdTMWt5eE0?usp=sharing

I extremely appreciate it.

Duc.

setBatchMode(true);
run("Set Measurements...", "area min perimeter bounding fit shape redirect=None decimal=4");
dir1=getDirectory("startup");
list1= getFileList(dir1);
for (i=0; i<list1.length; i++) {
   dirmain=dir1+list1[i];
   dir2=substring(dirmain,0,lengthOf(dirmain)-1)+"/" ;
   list2= getFileList(dir2);
   for (j=0; j<list2.length; j++) {
      open(dir2+list2[j]);
      path=dir2+list2[j];
      run("Subtract Background...", "rolling=45 light");
      dotIndex = lastIndexOf(path, ".");
      path = substring(path, 0, dotIndex); // remove extension
      saveAs("Jpeg", path+".jpg");
      setAutoThreshold("IsoData");
      //run("Convert to Mask"); 
      //run("Close-");
      //run("Watershed"); sometime Watershed works, other time is not.
      run("Analyze Particles...", "size=50-Infinity circularity=0.09-0.65 show=Outlines display clear include record");
      saveAs("Measurements", path+".txt");
      run("Save", "save=["+path+".tif]");
      run("Close");
      run("Close");
   }
}


#2

Hi @DucTran

before diving into solving overlap and out-of-focus image processing problems, I would like to ask you could envision making changes to your image acquisition setup?

option 1:
How about acquiring several optical sections and process in 3d?
this generates a lot more data, but the out of focus problem and the overlap might go away when attacking the problem in 3d instead of 2d.
Furthermore you could do volumetrics on your particles in case this is of interest to you.

option 2:
The images look like the recipient has quite a bit of volume (depth). I am guessing you take one image and extrapolate on the bigger volume (1 liter)?
If that is the case, how about opting for a flatter object carrier?

From the few images you uploaded I got the impression that optimizing acquisition might be a more robust way of tacking the overlap problem, given that the particles have no strong geometric constraint that allow straight forward filtering.

Concerning out-of focus objects; analyzing the gradient at the edges of the objects might give you already a good idea about the object contrast.

… just thinking while typing … :thinking:

Felix


#3

Hi @FelixM ,

Thank you very much for your time and suggestions. The idea of 3d image is great and I wish I could do that. Unfortunately, in our experiments, this is not an easy task. The aggregate images were captured when the aggregates were travelling with the flow at velocity of 0.4 m/s. And also, the windows for imaging somehow constrained due to the setup (please refer to the attached image).

The images that I uploaded are raw data without any extrapolation and/or modification. The depth of focus (of the camera) was 91 micrometer. I am not sure if I am able to change this.

I am aware that I should do something like analyzing the gradient at the edges; yet how can I integrate it in the code? I have from several thousand to 10x thousand images for each experiment.

Thank you very much, @FelixM.

Duc.

MixingTankSetup|690x387


#4

unfortunatly I cannot see that image.

You can produce a gradient image with pure imageJ producing a difference of Gaussian. Menu > Process > Filters > Gaussian Blur
Or with some third party plugins like the following:

Then you can measure some properties for each object by redirecting the particle analysis on the gradient image. In the following blog post you find some instructions on how to do that in a macro:

Heads-up : On problem with ImageJ1 ROI’s is that there is no easy way on how to use ring ROI’s (one report here). If the descriptors of the entire object do not yield conclusive information, you might what to restrain the gradient measurements exclusively on the objects border. If you can script imglib2, then there are possibilities. But if you do not like to do imagej2 scripts you might first want to give KNIME and it’s image processing plugins a try.

Hope that helps

Felix


#5

Hi @Felix,

Thank you very much for the input. I appreciate it. I will give it a try.

Have a good day,

Duc.


#6

@DucTran the out of focus objects have bigger pixel values, brighter. Only the in focus ones are really close to black. You might be able to use an intensity threshold to only measure objects that are very dark.

It’s the simplest way to throw out out of focus objects.

Better would be to use a smaller depth of field lens. The out of focus objects will be more blurry and less of a problem.

Or mount the sample between a glass microscope slide and a glass coversheet for a thin layer, or use a haemocytometer for a thicker but still quite thin layer. Then there won’t be any out of focus objects.
:wink:


#7

Hi @chalkie666,

Thank you very much for your comment. We actually have a Matlab script to filter out the out-of-focus (using gaussgradient). I just think ImageJ may do a better job, that is why I am trying to figure out how to do it with ImageJ.

We are measuring aggregates which are very fragile and move with the flow, so we are unable to take samples.

Thank you very much for your time and advice.

Duc.