首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >等效于label2idx MATLAB函数的Python

等效于label2idx MATLAB函数的Python
EN

Stack Overflow用户
提问于 2019-06-25 09:03:18
回答 2查看 877关注 0票数 3

在python中有label2idx()函数的库实现吗?

我希望将标签表示形式中的超像素提取为label2idx()函数精确返回的格式。

label2idx函数:https://in.mathworks.com/help/images/ref/label2idx.html

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-25 09:15:07

给定一个包含从label_arrmax(label_arr)的所有标签的标签数组,您可以这样做:

代码语言:javascript
运行
复制
def label2idx(label_arr):
    return [
        np.where(label_arr.ravel() == i)[0]
        for i in range(1, np.max(label_arr) + 1)]

如果您想放松包含所有标签的要求,可以添加一个简单的if,即:

代码语言:javascript
运行
复制
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文档中复制该示例:

代码语言:javascript
运行
复制
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]

但是,请注意,由于MATLAB和NumPy之间的差异,没有得到完全相同的结果,特别是:

  • MATLAB: FORTRAN风格的矩阵索引和基于1的索引
  • Python+NumPy: C风格的矩阵索引和基于0的索引

如果你想在MATLAB中得到相同的数字,你可以用这个代替(注意额外的.T+ 1):

代码语言:javascript
运行
复制
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)]
票数 4
EN

Stack Overflow用户

发布于 2019-06-25 09:18:23

MATLAB的label2idx输出给定标记图像的扁平指数(列-大有序)。

我们可以使用scikit-image's内置regionprops从标记的图像中获取这些索引。Scikit-image还为我们提供了一个内置的,以获取标记的图像,所以所有的工作与相同的包。执行过程会是这样的-

代码语言:javascript
运行
复制
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

样本运行-

代码语言:javascript
运行
复制
# 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])]

如果您需要像MATLAB这样按列的主要顺序排列的索引,只需转换图像,然后按-

代码语言:javascript
运行
复制
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中的索引是从1开始的。

替代使用SciPy获取标记图像

SciPy还内置了一个标签-图像:scipy.ndimage.label -

代码语言:javascript
运行
复制
from scipy.ndimage import label

L = label(a)[0]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56750400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档