Search code examples
python-3.xopencvimage-processingfijiimage-slicer

Computing the thickness of branches in a 2D image


I'd like to get a measure of the thickness of branches in an image. The following is the output obtained from Fiji.

enter image description here

I'd like to compute an average measure of the thickness associated with each edge. By edge, I mean the segment present between any two branching points.

Any directions on how to proceed will be really helpful.

Image source: ref

EDIT: Node is a junction point or the terminal points. Please let me know if it is not clear and if I have to explain it further. For instance, if we skeletonize the above image like the ones shown here, the junctions or terminal points will be nodes. If it helps, I can share a skeletonized version of the above image.

EDIT2: enter image description here

{1 -> {36.4156, 23.8112, 0.},
 2 -> {83.4779, 151.809, 0.}, 
 3 -> {182.451, 145.504, 0.},
 4 -> {227.385, 86.2469, 0.}, 
 5 -> {311.9, 218.811, 0.},
 6 -> {483.204, 190.795, 0.}, 
 7 -> {601.916, 226.427, 0.},
 8 -> {780.405, 312.889, 0.}, 
 9 -> {974.959, 274.093, 0.},
 10 -> {656.313, 209.944, 0.}, 
 11 -> {815.08, 182.186, 0.},
 12 -> {923.162, 121.453, 0.}, 
 13 -> {353.554, 34.5667, 0.},
 14 -> {479.314, 87.3631, 0.}, 
 15 -> {662.5, 119.5, 0.},
 16 -> {759.72, 99.8905, 0.}, 
 17 -> {539.501, 34.4999, 0.},
 18 -> {712.917, 26.8174, 0.}, 
 19 -> {896.5, 65.5, 0.},
 20 -> {143.654, 379.583, 0.}, 
 21 -> {203.382, 270.926, 0.},
 22 -> {311.084, 354.623, 0.}, 
 23 -> {495.5, 330.5, 0.},
 24 -> {643.872, 319.37, 0.}, 
 25 -> {794.571, 405.533, 0.},
 26 -> {415.864, 397.252, 0.}, 
 27 -> {624.794, 369.389, 0.},
 28 -> {488.5, 276.5, 0.}}

Solution

  • You can do distance transform. Multiply the resulting image by the skeleton. See an example. Decomposition the skeleton into segments and average over the segments. This will be the average line thickness. Matlab/Octave code:

    a=imread('IW.png');
    bw=im2bw(a, 0.1);
    skeleton=bwmorph(bw, 'skel', Inf);
    D = bwdist(~bw);
    imagesc(D.*single(skeleton));
    

    enter image description here

    Or this Matlab/Octave code:

    a=imread('IW.png');
    bw=im2bw(a, 0.1);
    skeleton=bwmorph(bw, 'skel', Inf);
    branchpoints=bwmorph(skeleton, 'branchpoints');
    se=strel('disk', 3);
    branchpoints=imdilate(branchpoints,se);
    segments=skeleton>branchpoints;
    segments=bwareaopen(segments, 8);
    stats = regionprops(segments,'Centroid', 'PixelIdxList');
    centroids = cat(1, stats.Centroid);
    D = bwdist(~bw);
    hold on
    %imagesc(D.*single(skeleton))
    imshow(a)
    for i=1:numel(stats)
        m(i)=mean(D(stats(i).PixelIdxList));
        text(centroids(i,1),centroids(i,2), num2str(m(i)), 'Color','blue');
    end
    

    Result: enter image description here