pythonfor-looptiffscipy.ndimage

Using Scipy.ndimage to iterate over Elevation Array


I have an elevation array from a .tif LiDAR surface. Example array below.

Existing_example_arrayV0 = [[ 0, 0, 1, 0, 0, 0, 0], 
                            [ 0, 1, 1, 1, 0, 0, 0], 
                            [ 0, 1, 1, 1, 1, 0, 0], 
                            [ 1, 1, 1, 1, 1, 0, 0], 
                            [ 0, 1, 1, 1, 1, 0, 0], 
                            [ 0, 1, 1, 0, 0, 0, 0]]

I am attempting to use scipy.ndimage to iterate over the array and add 100 to the array.

Existing_example_arrayV0[binary_erosion(Existing_example_arrayV0 >=1, structure=[[1,1,1]])] += 100

to produce the first iteration.

Existing_example_arrayV1 = [[ 0,  0,   1,   0,  0, 0, 0], 
                            [ 0,  1,  100,  1,  0, 0, 0], 
                            [ 0,  1,  100, 100, 1, 0, 0], 
                            [ 1, 100, 100, 100, 1, 0, 0], 
                            [ 0,  1,  100, 100, 1, 0, 0], 
                            [ 0,  1,   1,   0,  0, 0, 0]]

I'm not familiar with Binary Erosion so I am having a difficult time iterating to create the second iteration:

Existing_example_arrayV2 = [[ 0,  0,   1,   0,  0, 0, 0], 
                            [ 0,  1,  100,  1,  0, 0, 0], 
                            [ 0,  1,  100, 100, 1, 0, 0], 
                            [ 1, 100, 200, 100, 1, 0, 0], 
                            [ 0,  1,  100, 100, 1, 0, 0], 
                            [ 0,  1,   1,   0,  0, 0, 0]]

I attempted to create a for loop that would create the next step but am having issues getting it to run correctly.

import scipy.ndimage as binary_erosion
for i in range(0,1):
    binary_erosion(Existing_example_arrayV1>=1, structure=[[1,1,1]], iterations = i + 1)

I thought the range would just run the next iteration to produce Existing_example_arrayV2, but it is not. I am trying to add an iteration on top of the finished numpy array (V0 -> V1, V1 -> V2 etc.) to continue the cycle for however many iterations I need to run.


Solution

  • For me, this code does what you described:

    example_V2 = example_V0.copy()
    for i in range(1, 3):
        mask = binary_erosion(example_V0, iterations=i)
        example_V2[mask] += 100
    

    Each iteration, it adds 100 to the next layer.

    But your example steps seem that you don't want to add 100, but rather 99 for the first step. In this case, you can add a line at the end:

    example_V2[binary_erosion(example_V2)] -= 1
    

    If you wanted to do a full function which produces the nth iteration:

    def elevation_array(flat_array, n):
        out = flat_array.copy()
    
        for i in range(1, n+1):
            mask = binary_erosion(flat_array, iterations=i)
            out[mask] += 100
    
        if n > 0:
            out[binary_erosion(out)] -= 1
    
        return out