假设有一个标签数组label_arr
,其中包含从1
到max(label_arr)
的所有标签,你可以这样操作:
def label2idx(label_arr):
return [
np.where(label_arr.ravel() == i)[0]
for i in range(1, np.max(label_arr) + 1)]
if
,如下所示:
如果您想放宽所有标签的要求,可以添加一个简单的 if
条件语句,例如:
def label2idx(label_arr):
return [
np.where(label_arr.ravel() == i)[0]
if i in label_arr else np.array([], dtype=int)
for i in range(1, np.max(label_arr) + 1)]
仅为了复制MATLAB文档中的示例:
import numpy as np
import scipy as sp
import scipy.ndimage
struct_arr = np.array(
[[1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 1, 0],
[1, 1, 1, 0, 0, 0, 1, 0],
[1, 1, 1, 0, 0, 1, 1, 0],
[1, 1, 1, 0, 0, 0, 0, 0]])
label_arr, num_labels = sp.ndimage.label(struct_arr)
# label_arr:
# [[1 1 1 0 0 0 0 0]
# [1 1 1 0 2 2 0 0]
# [1 1 1 0 2 2 0 0]
# [1 1 1 0 0 0 0 0]
# [1 1 1 0 0 0 3 0]
# [1 1 1 0 0 0 3 0]
# [1 1 1 0 0 3 3 0]
# [1 1 1 0 0 0 0 0]]
def label2idx(label_arr):
return [
np.where(label_arr.ravel() == i)[0]
for i in range(1, np.max(label_arr) + 1)]
pixel_idxs = label2idx(label_arr)
for pixel_idx in pixel_idxs:
print(pixel_idx)
# [ 0 1 2 8 9 10 16 17 18 24 25 26 32 33 34 40 41 42 48 49 50 56 57 58]
# [12 13 20 21]
# [38 46 53 54]
def label2idx_MATLAB(label_arr):
return [
np.where(label_arr.T.ravel() == i)[0] + 1
for i in range(1, np.max(label_arr) + 1)]
label2idx
函数会输出给定标记图像的扁平化索引(按列主序排序)。scikit-image
内置的regionprops
函数从标记图像中获取这些索引。 Scikit-image
还为我们提供了一个内置函数来获取标记图像,因此所有操作都可以在同一个软件包中完成。实现代码如下 -from skimage.measure import label,regionprops
def label2idx(L):
# Get region-properties for all labels
props = regionprops(L)
# Get XY coordinates/indices for each label
indices = [p.coords for p in props]
# Get flattened-indices for each label, similar to MATLAB version
# Note that this is row-major ordered.
flattened_indices = [np.ravel_multi_index(idx.T,L.shape) for idx in indices]
return indices, flattened_indices
示例运行 -
# Input array
In [62]: a
Out[62]:
array([[1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 1, 0],
[1, 1, 1, 0, 0, 0, 1, 0],
[1, 1, 1, 0, 0, 1, 1, 0],
[1, 1, 1, 0, 0, 0, 0, 0]])
# Get labeled image
In [63]: L = label(a)
In [64]: idx,flat_idx = label2idx(L)
In [65]: flat_idx
Out[65]:
[array([ 0, 1, 2, 8, 9, 10, 16, 17, 18, 24, 25, 26, 32, 33, 34, 40, 41,
42, 48, 49, 50, 56, 57, 58]),
array([12, 13, 20, 21]),
array([38, 46, 53, 54])]
In [5]: idx,flat_idx = label2idx(L.T)
In [6]: flat_idx
Out[6]:
[array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23]),
array([33, 34, 41, 42]),
array([46, 52, 53, 54])]
0
开始,与MATLAB不同,MATLAB的索引从1
开始。scipy.ndimage.label
。from scipy.ndimage import label
L = label(a)[0]
np.where()
以更简单(可能更快)的方式解决这个问题。 - norok2
np.where(label_arr == label_value)
。 - norok2.ravel()
函数对label_arr
进行展平操作,然后循环遍历标签值。 - norok2