How to find the diameter of objects using image processing in Python?

前端 未结 2 499
生来不讨喜
生来不讨喜 2021-01-05 21:44

Given an image with some irregular objects in it, I want to find their individual diameter.

Thanks to this answer, I know how to identify the objects. Howeve

相关标签:
2条回答
  • 2021-01-05 22:18

    You could use skimage.measure.regionprops to determine the bounding box of all the regions in your image. For roughly circular blobs the diameter of the minimum enclosing circle can be approximated by the largest side of the bounding box. To do so you just need to add the following snippet at the end of your script:

    from skimage.measure import regionprops
    
    properties = regionprops(labels)
    print 'Label \tLargest side'
    for p in properties:
        min_row, min_col, max_row, max_col = p.bbox
        print '%5d %14.3f' % (p.label, max(max_row - min_row, max_col - min_col))
    
    fig = plt.figure()
    ax = fig.add_subplot(111)    
    ax.imshow(np.ma.masked_array(labels, ~blobs), cmap=plt.cm.gist_rainbow) 
    ax.set_title('Labeled objects')
    plt.xticks([])
    plt.yticks([])
    for ri, ci, li in zip(r, c, range(1, nlabels+1)):
        ax.annotate(li, xy=(ci, ri), fontsize=24)
    plt.show()
    

    And this is the output you get:

    Label   Largest side
        1        106.000
        2         75.000
        3         79.000
        4         56.000
        5        161.000
        6         35.000
        7         47.000  
    

    Labeled objects

    0 讨论(0)
  • 2021-01-05 22:28

    I would propose using a distance transform. So once you've got your labeled image you do:

    dt = ndimage.distance_transform_edt(blobs)
    slices = ndimage.find_objects(input=labels)
    radii = [np.amax(dt[s]) for s in slices]
    

    This gives the largest inscribed circle (or sphere in 3D). The find_objects function is quite handy. It returns a list of Python slice objects, which you can use to index into the image at the specific locations containing the blobs. These slices can of course be used to index into the distance transform image. Thus the largest value of the distance transform inside the slice is the radius you're looking for.

    There is one potential gothcha of the above code: the slice is a square (or cubic) section so might contain small pieces of other blobs if they are close together. You can get around this with a bit more complicated logic as follows:

    radii = [np.amax(dt[slices[i]]*(labels[slices[i]] == (i+1))) for i in range(nlabels)]
    

    The above version of the list comprehension masks the distance transform with the blob that is supposed to be indexed by the slice, thereby removing any unwanted interference from neighboring blobs.

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