Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python equivalent of label2idx MATLAB function

Is there any library implementation for the label2idx() function in python?

I wish to extract superpixels from the label representation to the format exactly returned by the label2idx() function.

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

like image 599
Ansh Khurana Avatar asked Apr 28 '26 13:04

Ansh Khurana


1 Answers

Given an array of labels label_arr containing all labels from 1 to max(label_arr), you can do:

def label2idx(label_arr):
    return [
        np.where(label_arr.ravel() == i)[0]
        for i in range(1, np.max(label_arr) + 1)]

If you want to relax the requirement of all labels being contained you can add a simple if, i.e.:

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)]

Just to replicate the example in the MATLAB docs:

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]

Note, however that you do not get the very same results because of the differences between MATLAB and NumPy, notably:

  • MATLAB: FORTRAN-style matrix indexing and 1-based indexing
  • Python+NumPy: C-style matrix indexing and 0-based indexing

and if you want to get the very same numbers you get in MATLAB you may use this instead (note the extra .T and the + 1):

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)]
like image 161
norok2 Avatar answered May 01 '26 02:05

norok2



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!