Fitting a smooth border to "rugged" shape

I have an MR image of the thigh weighted for the lean tissue (i.e. only the muscles and the skin are visible).
Using region growing I am able to segment the muscles in a satisfactory manner. However, the contour of the segmentation are somehow “rugged”, and I would like to “smooth” them. I thought that a good idea would be to somehow fit a smooth shape to the contour of the segmentation, as in this example image.
Since I am (relatively) familiar with Python and several preprocessing steps are already performed using scikit-image, I would like to to perform the process described using scikit-image. However, I am quite green about image processing, and I do not really know if there is an algorithm within the library that I could use for my aim.
Any tip or suggestion is more than welcome.

Hi @fnemmi-tonic ,! I think what you are looking for is an erosion-dilation smoothing procedure, which, in python, is apparently available in the skimage package
(Module: morphology — skimage v0.18.0 docs)

The trick would be to run several iterations of dilation followed by the same number of erosion steps. Depending on the order (erosion -dilation or dilation-erosion) and number of iterations, the smoothing procedure will either tend to keep small structures and smooth them or eradicate such structures. I haven’t used that particular package myself, though.

Hope this helps!

1 Like

Hi @fnemmi-tonic,

I am (still) not familiar with scikit-image and python but I would guess what helps is either getting the convex hull image or perform a morphological closing.

This is what I quickly did in Fiji with a combination of closing and opening (similar to the suggestion of @EL_Pollo_Diablo). In red you see the transferred outline to the original

1 Like

As others have mentioned already, the hand-drawn outline looks like the convex hulls of the shapes in question. If a non-python approach is allowed, here is an ImageJ-macro that does what you’ve sketched:

/* begin imagej-macro */
run("Duplicate...", " ");
setOption("BlackBackground", true);
run("Convert to Mask");
run("Analyze Particles...", "exclude add");
for ( i=0; i<n; i++ ) { 
   roiManager("select", i);
   run("Convex Hull");
   run("Interpolate", "interval=20 smooth adjust");
   run("Fit Spline");
   run("Add Selection...");
run("Overlay Options...", "stroke=red width=3 fill=none apply");
run("Select None");

Open the sample image as is in ImageJ or Fiji.
Paste the above code to an empty macro window (Plugins >> New >> Macro) and run it.

1 Like

to notQRV:
thank you for the script. Trying to run it and get an error:
[This command requires a selection in line 15 “run (“Fit spline” <)>;”]
Any suggestions? Please:)


Could you please run the following macro code on your original sample image:

/* begin imagej-macro */
run("Duplicate...", " ");
setOption("BlackBackground", true);
run("Convert to Mask");

You should then see a new image that looks like:

If this is not the case or in case it looks differently, then please tell me what happens or post the image that is generated.

Thank you, much appreciated! My image has objects that are quite heterogeneous, I am not sure that mask is working. Some of them are also “touching” each other…
The error is still the same if after the masking/inverting I try to run the encircling script.
What I ultimately need is to get a separate image of each object (these are embryos).

20-1.tif (439.6 KB)

The macro is not suited for cases like yours.
The macro was written for finding the convex hull of binary-valued structures, not for structures in colour or gray-value images.

You must first segment your image and binarize (threshold) it.
Whether this is easily possible, is a different question that should not be discussed in this thread.

yes, I am starting to understand it… Binarizing I did but segmentation is something new for me. Thank you very much, I will see how it goes and create a new thread if needed.