Segmentation in Time-lapse

Practice_sequence
Hi, I am trying to segment the top 3 cells in the attached time-lapse image sequence of cellular electrodeformation by writing a macro. The macro I write in process>batch>macro is as follows:
makeRectangle(107, 0, 178, 142);
run(“Crop”);
setAutoThreshold(“Default no-reset”);
//run(“Threshold…”);
setOption(“BlackBackground”, false);
run(“Convert to Mask”);
run(“Open”);
run(“Dilate”);
run(“Dilate”);
run(“Dilate”);
run(“Fill Holes”);
run(“Erode”);
run(“Erode”);
run(“Erode”);
The challenge I face is that while some images are well segmented but others (~25-35 % are not!). I tried the trainable WEKA segmentation as well but it also gives similar results. I attach below a snapshot of my batch macro result
Capture
As you can see 5 out of 20 images are badly segmented. I have a total of about 400 images. Please suggest how I can correct or improve my segmentation with macro script.
Thank you.

Hi Danish,
Filtering your images before the thresholding should help. In the code below, I have used the median filter. I also used a slightly different threshold method - “Mean” appears to be working fine. It will pick up quite a bit of background as well. However, that is not a problem as it is easy to separate your cells from the background using the Particle Analyzer and filter the particles by circularity. In the sample code below, I used 0.7 to 1. I also added a size cut off to only include structures larger than 1000 pixels in area. The masks of the selected particles are shown in a new image stack and they are also added to the ROI manager.

On closer inspection I realised that it misses the occasional cell, but this might give you some ideas and you might be able to further improve on the performance by playing around with the filter/threshold parameters.

Hope this helps,
Volko


run("Duplicate...", "duplicate");
makeRectangle(107, 0, 178, 142);
run("Crop");
run("Median...", "radius=3 stack");
setAutoThreshold("Mean");
setOption("BlackBackground", true);
run("Convert to Mask", "method=Default background=Light black list");
run("Analyze Particles...", "size=1000-Infinity circularity=0.70-1.00 show=Masks display include add stack");
1 Like

Thanks a lot @Volko for giving it a try. I tried your code as it is and also with slightly different values here and there in it. It performed better in terms of the quality of segmentation but still it missed a cell in 49/141 images (34.7%). Unfortunately, the primary issue still remains.
I tried boolean operation (Image_n OR Image_n+1) on two adjacent images (in a loop to cover all pairs), so that most of the missing cells would appear i.e. a cell still missing in 10/141 images (7%). Though the boolean trick is a deviation from the domain of segmentation i think.
My boolean trick (given below) runs better on your segmentation code! So, this exchange actually improved things. I hope there is a way to correct the remaining 7% of missing cells too.

#@ File (label = "Input directory", style = "directory") directory
list = getFileList(directory);
//Array.show(list);
for (i = 0; i < list.length -1; i++) {
j = i+1;
file_A = list[i];
file_B = list[j];
//print(file_A, file_B)
open(file_A);
open(file_B);
imageCalculator("Add create", file_B, file_A);
saveAs("TIFF","C:\\Users\\DSham\\Desktop\\Online Courses\\ImageJ_Fiji\\Images from my previous research\\Ljubljana\\Empty Folder\\"+file_B);
close(file_A);
close(file_B);

}

Hi Danish,
I had another look at your images and added a bandpass filter to enhance the edges. As far as I can see the modified code only misses 2 out of the 423 cells in your example. Perhaps this could be further improved, but it is quite easy to find the images with the missing cells and manually edit them if necessary (or simply replace the missing values with an average of the measurement of the adjacent two images).
Here is the modified code:

run("Duplicate...", "duplicate");
makeRectangle(107, 0, 178, 142);
run("Crop");
run("Bandpass Filter...", "filter_large=40 filter_small=3 suppress=None tolerance=5 saturate process");
run("Median...", "radius=3 stack");
setAutoThreshold("Mean");
setOption("BlackBackground", true);
run("Convert to Mask", "method=Default background=Light black list");
run("Analyze Particles...", "size=1000-Infinity circularity=0.70-1.00 show=Masks display include add stack");
print("Found cells: "+roiManager("count")+", Expected cells: "+3*nSlices);

Cheers,
Volko

Hi @dsham,

depending on the context you need to perform the segmentation, and the amount of particles to process, the utlity Cell Outliner from the GDSC plugin collection (GDSC ImageJ Plugins : Image J Analysis : ... : Sussex Centre for Genome Damage and Stability : Lifesci : Schools : Staff : University of Sussex) could be an option, or not.
The caveat is that it requires to mark all the cells of interest in one frame, using the multi-point selection tool. For your specific image the results are already satisfactory using the default values. Increasing the number of iterations to 6 this is the result
Example
From a macro the command would be

run("Cell Outliner", "cell_radius=25 tolerance=0.80 kernel_width=13 dark_edge kernel_smoothing=1 polygon_smoothing=1 weighting_gamma=3 iterations=6 dilate=0 all_slices");

I hope it helps.
Giovanni

Hi, the following macro will detect quite cleanly two of the 3 cells across the whole sequence using this method:
https://blog.bham.ac.uk/intellimic/g-landini-software/threshold-from-gradient-of-region-boundaries/
(The third touching the border is not detectable)

a=getTitle();
s=nSlices();
setBatchMode(true);
for (i=1;i<=s;i++){
  selectWindow(a);
  setSlice(i);
  run("Duplicate...", "title="+i);
  run("Threshold Regional Gradient", "circularity=0.60 minimum=400 maximum=6000 fill_phase fill_detected method=Fast");
  selectWindow("Result");
  rename("TRes"+i);
  selectWindow(i);
  close();
}
run("Images to Stack", "name=Stack title=TRes use");
setBatchMode(false);

You could add a white line at the very top border to force the detection of the top cell by adding at the very start of the macro:

run("Add Borders", "top white stack");

but it is best to not do such things and instead get the images properly centred from the start.
Unfortunately the text burnt into the image interferes with the bottom cell detection. The largest cell does not show a continuous gradient, so it won’t be detected.
To run all this you need to add the Morphology collection update site. Make sure you have Fiji updated or in ImageJ download the latest version from here (updated yesterday):
https://blog.bham.ac.uk/intellimic/g-landini-software/
where is says “Download the full Morphology set as a single zip file from here”.
If you find it useful, please cite the segmentation method:
https://onlinelibrary.wiley.com/doi/pdf/10.1111/jmi.12474

Thank’s a lot again @Volko. This one gave nice results. I also found the Cell outliner utility suggested by @gcardone very nice. Thanks to all for helping me move forward.

You may want to give CellPose a try, or possibly StarDist. CellPose has given surprisingly good segmentation results for mono images.