Extracting Hollow circles from Phase Contrast Images [Solved]

Hello, I am an undergrad student at the University of Central Florida working with Phase Contrast images that I obtained by experiment at Argonne’s National Labs Advanced Photon Source. I have been working with these images for the past three months and have reached a wall. I have written hundreds of lines of code in MATLAB, utilizing every package and have worked extensively with ImageJ (Fiji) but with little improvement.

My Problem:
I need to isolate the small particles in this image. They are hollow circles that are very similar to the Background. They are difficult to see in a static frame so I have attached a gif.
Image(hard to see anything):

Close up:

Some of them circled:

GIF (make it full screen to see)

The images are 16bit tiffs. 1024x1024

My current approach is two subtract the next image from the current image, and then multiply it by a factor of 10-100.

I am then using a circle algorithm to find the circles and fill them in for I can track them.
Even through I spent a lot of time developing this, I am not to happy with it. Primarily since the images are subtracted images (ghost particles) and the circle finder has inconsistencies between frames.

I would prefer to alter the original images and exact the circle features, but I can figure out how. Can someone please help?!

I recently discovered that the circle finder can “kinda” find the circles in the orginal images (i.e. the white circles in the second image) but I am unsure of the error over an entire image.

Here is a link to a google folder with 10 images:

I don’t have a direct solution, but here’s two small ideas.

Do you have an image of the background without any circles? As you noted, your current approach gives you ghost particles because you are combining two image frames with different circles. If you don’t have it, you could approximate a background by averaging or taking the median of all 11 (or however many you have) images and it should get close given how low contrast the circles are. That may help improve the accuracy.

I’m afraid the best way to validate the results/find the error may be to do an image or two manually. E.g., search by eye to find each circle, annotate it, and then count whether your method found it or not. You can probably overlay the method results/manual annotation to more easily compare.

Edit: You may also be able to use plugins like BaSiC to find the background more robustly than mean/median, but a quick look seemed to give good results due to how similar the images are.

Thank you mpinkert!

I wish I did, one of my mistakes during the experiment was that I did not get a baseline image (one without circles).

I have attempted to recreate a background image before without much luck but then again my image skills have drastically increased since then so I will try that approach once more. Unfortunately, I have around 40K images to process, so individually classifying them is not favorable. (all the images are the same besides the path the circles take)

I just installed the BaSiC plugin, but can’t find much documentation on what the different settings do. Trial error approach :sweat_smile:

Essentially if the border can become more defined in some way, it would make edge detection and segmentation a viable solution.

Not sure if it will help, but try this:

  1. Get your stack of images and smooth all the slices with a gaussian blur of size 2
  2. Do an average Z-projection of the stack
  3. Divide the stack by the Z-average, converting to 32 bits
  4. Adjust the contrast



That is exactly what I need:grinning: !!!

This is honestly such a relief, I was stuck at a wall for so long.
Could you possibly record the macros with the record macros plugin? Your image looks absolutely perfect.

Here’s my attempt: (video Link)


  1. Import the images as a stack (Xray)

  2. Apply Gaussian blur ( I did the 3d gaussian don’t think it matters, I just clicked for the first one)

  3. Go to Stacks -> Z-Project … Start slice 1 end slice 11… Projection type = Average Intensity

  4. Image calculator (Divide)
    Image1 = Xray (Gaussian blur)
    Image2 = Z-Average
    --------> Process all 11 images? [ Yes ]

  5. Take Result-> Image -> Adjust -> Brightness/Contrast
    (I messed with it quickly but couldnt get your result, I can mess with it more)
    I did not know what to do for “Set Display Range” , Propagate to all images? Or just click apply?

I noticed a little bit of blurring when I clicked play, I dont know if I did something wrong.

I am going to repeat this and adjust things. I wanted to reply quickly!


Glad it worked for you.
You forgot in step 4 to make it 32bit result.
The extra blurring might be because you used the 3D, not the 2D gaussian blurred. I would use the 2D.
Please mark the thread as “solved”.

Yes, I did it a few times and got it to work!

For the sake of understanding, what exactly is being done? I’m currently reading some papers on intensity projection but a general idea would really help.

  1. Gaussian blur-> Reduce noise (smoothing)

Thank you

As far as I understand it;

  • The smoothing reduces the noise and small changes in the images
  • The average z-projection gives you a good estimate of the background by averaging all images together, since the moving circles are averaged out.
  • Division through the average removes this backround from all images
  • The contrast adjustment shows the image nicely to you