3D Subpixel edge detection for advanced surface determination

Hi there,
I’m starting using FIJI for post-processing of 3D image stack, created by industrial CT scanners.
I’m interested in subpixel approaches to edge detection and surface extraction.
Actually I succed in loading RAW stacks, 3D cropping, visualizing in 3D viewer as surfaces (with a thresold value manually extracted from the average histogram) and exporting as stl.
There are some limitations: 3D viewer works with 8bit only, and the resulting surface (marching cubes method?) is not as accurate as I need.

Now I would like to know if anybody had tried a local approach for surface determination. That means for instance checking locally for the maximum gradient across a starting ISO50 contour, and adjusting the surface position according to it.
Multimaterial object suffers from a local over(or under) estimation of the surface position, if a single ISO value is used.
It would be great to have a plugin that:
-works on an image stack
-requires a first ISO value estimation (manual or hang, otsu…)
-estimates a first approximation surface position
-adjust it locally according to local gray value gradients normal to the initial surface

I found something interesting here: https://www.researchgate.net/publication/220778375_Robust_Surface_Detection_for_Variance_Comparison_and_Dimensional_Measurement

It would be also very useful to plot a bigger Histogram, in order to check for various peaks in the material area. Is there the possibility to enlarge the histogram in FIJI?

Thansk to all for the attention


Hi @mading,

Do you have by any chance a sample image that you could share ?



Hi @NicoKiaru, yes thanks.
abete.zip (3.0 MB)

It’s a cropped image, with a spruce sample in it.
Voxel is isotropic.
A good example of “multimaterial” object.

You can have a look that at LimeSeg (https://imagej.net/LimeSeg), (disclaimer: I wrote most of it). It’s doing a pretty good job with finding the surface, by searching for local 3D maxima:

There are some tutorials in the documentation. Depending on the size of the image you’d like to segment and on the degree of automation you would like, it may fit or not your application.



Thanks Nicolas.
will definetely try it. A very well done documentation also.
What does the surfaces on the left represent? the wood rings?

Hi Nicolas, I gave a try and it’s interesting how it detect the growth rings.

Is there the possibility to treat the wood piece as one?
I’m looking for this kind of result:


Woops, ok I thought you wanted to detect the surface of the growth rings.
In this case LimeSeg is probably not the right tool. I tried a few things but the surface detection of the whole piece is not working. It’s too affected by the local maxima of wood rings.

If you haven’t tested it before, maybe you can give a try to a pixel classification approach, by using Weka or iLastik to create a mask, before doing a marching cube surface extraction ?

Hi Nicolas.
Thanks for your efforts!

In fact I want the object surface, and the maximum precision available.

Otsu or ISO50 thresold is usually enough for the first approximation surface and for running marching cubes or Flying Edges. On other software, of course.
In FIJI I still have to find how to do it properly.

But I’m looking for something beyond marching cubes: fitting surfaces locally to maximum gradient rather than to a global ISO value.
This way surfaces are less effected by material grayvalue variation: denser areas are less overestimated and lighter areas (and closer to bkg) are less underestimated.
Cited paper gives a better explanation.

Is this sort of what you were looking for? It is volume rendered in 3D Viewer but you can go to the edit mode and have it rendered as a surface.
You will have to put it in Plugins > 3D Viewer and go from there.

Sent the wrong one for a stack, here is the tiff. image.abeteTiff.tif (9.7 MB)
Sorry about that.

Hi there Robert.
Using 3Dviewer with a ISO50 thresold value (77) gives:

Exported and compared to reference, deviations are somewhere more than twice the voxel size (112 microns):

3Dviewer creates a jagged surface, due to the fact that slices are almost parallel to the upper surface.
reference takes into account and does not show this behaviours:

fiji 77:


Hi madding,
Yes, I only cleared the noise, I did not modify the main data in any way, such as smoothing, contrast,etc. etc.

Hi Robert,
thanks for reply. I can’t say how close they are, since also the image in your second post refers to something different that the 3D viewer screenshot.

Hello again,
Yes the second post (the correct one) was rendered in 3D Viewer in Volume mode, where you were interested in Surface mode. I simply left it to you to decide. By using the volume mode you can see and therefore determine the spacing between the layers.
Keep asking if you have any more questions, we want to help you obtain what you need.

Hi Robert,
even this does not add content to the discussion: I downloaded the image you posted in the and it looks like the tiff image stack I uploaded.

By the way. I hope somebody made a filter-plugin for fitting surfaces to local grayvalue variation. If so, it would help me.