Python 图像 - 从图像骨架中查找最大分支

问题描述 投票:0回答:2

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

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

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

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

python image opencv image-processing scikit-image
2个回答
8
投票

我相信你可以使用OpenCV来做以下事情:

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

  1. 在各个角落添加黑色像素

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


7
投票

有一个很棒的 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()

输出:

© www.soinside.com 2019 - 2024. All rights reserved.