Accurate estimation of length of 3D skeleton

length
skeleton-analysis
3d
Tags: #<Tag:0x00007fd543227660> #<Tag:0x00007fd5432274d0> #<Tag:0x00007fd543227368>

#1

Hi all,

Would you know about an efficient (memory, speed) algorithm to accurately estimate the length of a 3D skeleton stored as a binary mask with non isotropic sampling (Z Ratio not equal to 1)?

A simple approximation is probably to resample the stack prior to skeletonization and count the number of skeleton pixels, but this is not accurate and I would like to avoid resampling.

Best,
S.


#2

Hi @SebT,

I think Analyze Skeleton (Analyze > Skeleton > Analyze Skeleton (2D/3D)) handles anisotropic data well. The following macro works as expected:

run("Bat Cochlea Volume (19K)");
id = getImageID();
run("Skeletonize (2D/3D)");

// Isotropic 1/1/1
selectImage(id);
run("Properties...", "channels=1 slices=114 frames=1 unit=um pixel_width=1.0000 pixel_height=1.0000 voxel_depth=1.0000");
run("Analyze Skeleton (2D/3D)", "prune=none calculate");
a = getResult("Longest Shortest Path", nResults-1);
print("Sampling 1:1:1 path length: " + a);

// Anisotropic 1/1/2
selectImage(id);
run("Properties...", "channels=1 slices=114 frames=1 unit=um pixel_width=1.0000 pixel_height=1.0000 voxel_depth=2.0000");
run("Analyze Skeleton (2D/3D)", "prune=none calculate");
a = getResult("Longest Shortest Path", nResults-1);
print("Sampling 1:1:2 path length: " + a);

// Isotropic 2/2/2
selectImage(id);
run("Properties...", "channels=1 slices=114 frames=1 unit=um pixel_width=2.0000 pixel_height=2.0000 voxel_depth=2.0000");
run("Analyze Skeleton (2D/3D)", "prune=none calculate");
a = getResult("Longest Shortest Path", nResults-1);
print("Sampling 2:2:2 path length: " + a);

It prints:

Sampling 1:1:1 path length: 650.5267
Sampling 1:1:2 path length: 913.4677
Sampling 2:2:2 path length: 1301.0534

Largest shortest path output modification
#3

Thanks Jan! About 33% increase in length for x2 Z factor is actually what you would expect for randomly oriented segments. I should then have a look at the code to see how it is implemented…