Search code examples
pythonarraysnumpyscipyndimage

label 3d numpy array with scipy.ndimage.label


I've got a large 3d numpy array which consists of ones and zeros. I would like to use the scipy.ndimage.label tool to label the features in each sub-array (2d).

A subset of the 3d-array looks like:

import numpy as np
from scipy.ndimage import label

subset = np.array([[[1, 0, 0],
                    [1, 0, 1],
                    [0, 0, 0]],

                   [[0, 0, 0],
                    [1, 0, 1],
                    [0, 0, 1]],

                   [[0, 0, 0],
                    [1, 0, 0],
                    [0, 1, 1]],

                   [[0, 0, 0],
                    [1, 0, 0],
                    [1, 1, 1]]], dtype=uint8)

When I use the label tool on a small part of this subset is works correct:

>>>label(subset[0:3])    
(array([[[1, 0, 0],
         [1, 0, 2],
         [0, 0, 0]],

        [[0, 0, 0],
         [1, 0, 2],
         [0, 0, 2]],

        [[0, 0, 0],
         [1, 0, 0],
         [0, 2, 2]]]), 2)

However, when I use the entire subset the label tool is not working properly:

>>>label(subset)
(array([[[1, 0, 0],
         [1, 0, 1],
         [0, 0, 0]],

        [[0, 0, 0],
         [1, 0, 1],
         [0, 0, 1]],

        [[0, 0, 0],
         [1, 0, 0],
         [0, 1, 1]],

        [[0, 0, 0],
         [1, 0, 0],
         [1, 1, 1]]]), 1)

Any ideas how this problem can be tackled?

ps. The complete array which I am trying to label consists of 350219 2d arrays.


Solution

  • I answered this question with the help of dan-man.

    I had to define a new 3D structure for the label tool:

    import numpy as np
    from scipy.dimage import label
    
    str_3D = np.array([[[0, 0, 0],
                        [0, 0, 0],
                        [0, 0, 0]],
    
                       [[0, 1, 0],
                        [1, 1, 1],
                        [0, 1, 0]],
    
                       [[0, 0, 0],
                        [0, 0, 0],
                        [0, 0, 0]]], dtype='uint8')
    

    Now the label returns the following for my subset:

    >>> label(subset, structure=str_3D)
    # outputs:
    (array([[[1, 0, 0],
             [1, 0, 2],
             [0, 0, 0]],
    
            [[0, 0, 0],
             [3, 0, 4],
             [0, 0, 4]],
    
            [[0, 0, 0],
             [5, 0, 0],
             [0, 6, 6]],
    
            [[0, 0, 0],
             [7, 0, 0],
             [7, 7, 7]]]), 7)