2

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.

Patstro
  • 69
  • 6

2 Answers2

1

You have not used the result of binary erosion to modify your original array in the loop. We want to use the eroded image to add 100 to certain elements in your original array.

Here is a better version of your loop:

import numpy as np
from scipy.ndimage import binary_erosion

Existing_example_arrayV0 = np.array([[ 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]])

for i in range(1, 3):  # Change the number of iterations as needed
    erosion_mask = binary_erosion(Existing_example_arrayV0 >= 100, structure=np.ones((3, 3)), iterations=i)
    Existing_example_arrayV0[erosion_mask] += 100
Saxtheowl
  • 4,136
  • 5
  • 23
  • 32
1

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
Jacob Stuligross
  • 1,434
  • 5
  • 18