Locating the end points of a bridge-like structure in an image

后端 未结 6 1927
隐瞒了意图╮
隐瞒了意图╮ 2021-02-08 02:14

How do I locate the end points of a bridge-like structure in an image?

Below is a generalized representation.

相关标签:
6条回答
  • 2021-02-08 02:57

    Here you have a code example in Mathematica, probably not optimal:

    f[i_] := 
       Module[{t, i2, w, z, neighbours, i3, cRed}, 
      (t = Thinning[ColorNegate@i, 15]; 
       i2 = ImageData@Binarize[ DeleteSmallComponents[
            ImageSubtract[t, Dilation[Erosion[t, 1], 1]], 100], .1];
    
        For[w = 2, w < Dimensions[i2][[1]], w++,
         For[z = 2, z < Dimensions[i2][[2]], z++,
          If[i2[[w, z]] == 1 && i2[[w + 1, z + 1]] == 1, 
             i2[[w, z + 1]] = i2[[w + 1, z]] = 0];
          If[i2[[w, z]] == i2[[w - 1, z - 1]] == 1, 
             i2[[w, z - 1]] = i2[[w - 1, z]] = 0];
          If[i2[[w, z]] == i2[[w + 1, z - 1]] == 1, 
             i2[[w, z - 1]] = i2[[w + 1, z]] = 0];
          If[i2[[w, z]] == i2[[w - 1, z + 1]] == 1, 
             i2[[w, z + 1]] = i2[[w - 1, z]] = 0];
          ]
         ];
    
        neighbours[l_, k_, j_] := 
          l[[k - 1, j]] +     l[[k + 1, j]] +     l[[k, j + 1]] + l[[k, j - 1]] + 
          l[[k + 1, j + 1]] + l[[k + 1, j - 1]] + l[[k - 1, j + 1]] + 
          l[[k - 1, j - 1]];
    
        i3 = Table[
          If[i2[[w, z]] ==1,neighbours[i2, w, z], 0],{w,2,Dimensions[i2][[1]]-1}, 
                                                     {z,2,Dimensions[i2][[2]]-1}];
        cRed = 
         ColorNegate@Rasterize[Graphics[{Red, Disk[]}], ImageSize -> 15];
    
        ImageCompose[
         ImageCompose[i, 
          cRed, {#[[2]], Dimensions[i2][[1]] - #[[1]]} &@
           Position[i3, 1][[1]]], 
          cRed, {#[[2]], Dimensions[i2][[1]] - #[[1]]} &@
           Position[i3, 1][[2]]])];
    

    enter image description here

    0 讨论(0)
  • 2021-02-08 03:07

    One interesting feature that found is the junction point in the skeleton which has the least value of the distance function of the complement of the object associated with it.

    X - object set in black in input image D(X) - Distance function of object X D(~X) - Distance function of the complement of the object - this would usually resemble the skeletonization of the object set by itself.

    Thus the basic intuition here is that the object X's topology is such that near the heavy heads one finds pinch - a place where you are sure to have a junction point in the skeleton - and at the same time a low value of the distance function of the complement of the object. The neck or pinch produces a minimum here at the junction point.

    Maybe this idea needs some tuning - but i guess one can work around.

    0 讨论(0)
  • 2021-02-08 03:09

    Solution using Python, NumPy, Pymorph and Mahotas:

    import pymorph as m
    import mahotas
    from numpy import where, reshape
    
    image = mahotas.imread('input.png') # Load image
    
    b1 = image[:,:,0] < 100 # Make a binary image from the thresholded red channel
    b2 = m.erode(b1, m.sedisk(4)) # Erode to enhance contrast of the bridge
    b3 = m.open(b2,m.sedisk(4)) # Remove the bridge
    b4 = b2-b3 # Bridge plus small noise
    b5 = m.areaopen(b4,1000) # Remove small areas leaving only a thinned bridge
    b6 = m.dilate(b3)*b5 # Extend the non-bridge area slightly and get intersection with the bridge.
    
    #b6 is image of end of bridge, now find single points
    b7 = m.thin(b6, m.endpoints('homotopic')) # Narrow regions to single points.
    labelled = m.label(b7) # Label endpoints.
    
    x1, y1 = reshape(where(labelled == 1),(1,2))[0]
    x2, y2 = reshape(where(labelled == 2),(1,2))[0]
    
    outputimage = m.overlay(b1, m.dilate(b7,m.sedisk(5)))
    mahotas.imsave('output.png', outputimage)
    

    Output

    0 讨论(0)
  • 2021-02-08 03:11

    You could also try running a moving window over the image with a filter that is sum of the pixel values inside. Tune the size to say double the size of the bridge width. You should expect to see a fairly sharp transition when you run off the bridge onto the shore.

    0 讨论(0)
  • 2021-02-08 03:13

    Here is a code example to locate branch points after skeletonizing the image:

    import pymorph as m
    import mahotas
    from numpy import array
    
    image = mahotas.imread('1.png') # load image
    
    b1 = image[:,:,1] < 150 # make binary image from thresholded green channel
    
    b2 = m.thin(b1) # create skeleton
    b3 = m.thin(b2, m.endpoints('homotopic'), 15) # prune small branches, may need tuning
    
    # structuring elements to search for 3-connected pixels
    seA1 = array([[False,  True, False],
           [False,  True, False],
           [ True, False,  True]], dtype=bool)
    
    seB1 = array([[False, False, False],
           [ True, False,  True],
           [False,  True, False]], dtype=bool)
    
    seA2 = array([[False,  True, False],
           [ True,  True,  True],
           [False, False, False]], dtype=bool)
    
    seB2 = array([[ True, False,  True],
           [False, False, False],
           [False,  True, False]], dtype=bool)
    
    # hit or miss templates from these SEs
    hmt1 = m.se2hmt(seA1, seB1)
    hmt2 = m.se2hmt(seA2, seB2)
    
    # locate 3-connected regions
    b4 = m.union(m.supcanon(b3, hmt1), m.supcanon(b3, hmt2))
    
    # dilate to merge nearby hits
    b5 = m.dilate(b4, m.sedisk(10))
    
    # locate centroids
    b6 = m.blob(m.label(b5), 'centroid')
    
    outputimage = m.overlay(b1, m.dilate(b6,m.sedisk(5)))
    mahotas.imsave('output.png', outputimage)  
    

    sample output sample output

    0 讨论(0)
  • 2021-02-08 03:14

    A generic approach comes to mind:

    1) trace the outline and turn it into a path. So there is one path that goes all around the shape, it being made out of line segments

    2) look for the stem - the place on the path where the line segments are approximately parallel for some distance (a spatial index e.g. octree or kdtree will help keep the search localised)

    3) follow the path in some direction until the two sides suddenly diverge. That's an endpoint to the stem

    4) follow the path in the other direction to find the other endpoint

    0 讨论(0)
提交回复
热议问题