【问题标题】:Python Image - Finding largest branch from image skeletonPython Image - 从图像骨架中找到最大的分支
【发布时间】:2019-04-28 03:02:27
【问题描述】:

我有以下形状的骨架图像:

我想从骨架中提取“最大的分支”:

我知道也许我需要提取连接点并从该点划分界线(?),但我不知道该怎么做。

有没有办法使用 Python Scikit Image 或 OpenCV 来做到这一点?

【问题讨论】:

    标签: python image scikit-image opencv-python


    【解决方案1】:

    我相信你可以使用 OpenCV 做到以下几点:

    1. 使用HarrisCorner 检测图像中的所有角。这将为您提供所示的三个绿色点(我画了一个完整的圆圈以突出显示该位置)。

    1. 在所有角落添加黑色像素

    2. 使用findContours获取图片中的所有分支。然后使用arcLength检查每个轮廓的长度,得到最长的。

    【讨论】:

    【解决方案2】:

    有一个很棒的 python 包,用于使用 python 分析骨架,称为 FilFinder ($pip install fil_finder),它优雅地解决了这个问题。下面是从他们的tutorial 中采用的代码。

    生成骨架:

    import numpy as np
    import cv2
    import matplotlib.pyplot as plt
    from fil_finder import FilFinder2D
    import astropy.units as u
    
    skeleton = cv2.imread("./data/XmviQ.png", 0) #in numpy array format
    
    fil = FilFinder2D(skeleton, distance=250 * u.pc, mask=skeleton)
    fil.preprocess_image(flatten_percent=85)
    fil.create_mask(border_masking=True, verbose=False,
    use_existing_mask=True)
    fil.medskel(verbose=False)
    fil.analyze_skeletons(branch_thresh=40* u.pix, skel_thresh=10 * u.pix, prune_criteria='length')
    
    # Show the longest path
    plt.imshow(fil.skeleton, cmap='gray')
    plt.contour(fil.skeleton_longpath, colors='r')
    plt.axis('off')
    plt.show()
    

    输出:

    在您的问题中,您对沿图对应于骨架的最长路径不感兴趣,而是对最长分支的路径感兴趣。继续上面的代码块,下面的脚本可以解决问题。我添加了数据框以可视化 FilFinder 自动生成许多有关骨架的有趣信息。

    import pandas as pd
    plt.imshow(fil.skeleton, cmap='gray')
    
    # this also works for multiple filaments/skeletons in the image: here only one
    for idx, filament in enumerate(fil.filaments): 
    
        data = filament.branch_properties.copy()
        data_df = pd.DataFrame(data)
        data_df['offset_pixels'] = data_df['pixels'].apply(lambda x: x+filament.pixel_extents[0])
    
        print(f"Filament: {idx}")
        display(data_df.head())
    
        longest_branch_idx = data_df.length.idxmax()
        longest_branch_pix = data_df.offset_pixels.iloc[longest_branch_idx]
    
        y,x = longest_branch_pix[:,0],longest_branch_pix[:,1]
    
        plt.scatter(x,y , color='r')
    
    plt.axis('off')
    plt.show()
    

    输出:

    【讨论】:

      猜你喜欢
      • 2017-08-19
      • 2013-04-27
      • 2021-01-04
      • 2017-06-02
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      相关资源
      最近更新 更多