1

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

The below code erodes the image equally from all sides.

    for i in range(0, 1):  
    erosion_mask = binary_erosion(Existing_example_arrayV0 >= 100, structure=np.ones((3, 3)), iterations=i)
    Existing_example_arrayV0[erosion_mask] += 100

    Proposed_example_array = [[ 0,  0,   1,   0,   0,  0, 0], 
                              [ 0,  1,  101,  1,   0,  0, 0], 
                              [ 0,  1,  101, 101,  1,  0, 0], 
                              [ 1, 100, 101, 101,  1,  0, 0], 
                              [ 0,  1,  101, 101,  1,  0, 0], 
                              [ 0,  1,   1,   0,   0,  0, 0]]

Is there a way to change the structure to only erode the image from one side to produce the below proposed_example_array?

Eroded from left only:

    Proposed_example_array = [[ 0,  0,   1,   0,   0,  0, 0], 
                              [ 0,  1,  101, 101,  0,  0, 0], 
                              [ 0,  1,  101, 101, 101, 0, 0], 
                              [ 1, 100, 101, 101, 101, 0, 0], 
                              [ 0,  1,  101, 101, 101, 0, 0], 
                              [ 0,  1,  101,  0,   0,  0, 0]]

Eroded from right only:

    Proposed_example_array = [[  0,   0,    1,   0,  0,  0, 0], 
                              [  0,  101,  101,  1,  0,  0, 0], 
                              [  0,  101,  101, 101, 1,  0, 0], 
                              [ 101, 101,  101, 101, 1,  0, 0], 
                              [  0,  101,  101, 101, 1,  0, 0], 
                              [  0,  101,   1,   0,  0,  0, 0]]
Patstro
  • 69
  • 6
  • In your first proposed example array, should the element at y=4 x=3 not be 1? It's on the edge. – Reinderien Jul 16 '23 at 14:56
  • Yes! I believe you are correct. Do you have any recommendations to achieve the desired output array? – Patstro Jul 16 '23 at 14:58
  • Is the input guaranteed to have at least one non-zero element in each row? – Reinderien Jul 16 '23 at 15:17
  • Yes! the input array will always have at least one non-zero element in each row. I have been doing a fair bit of research and I'm not positive if I can achieve the desired output by changing the structure? But it seems to be my more promising lead. – Patstro Jul 16 '23 at 15:19

1 Answers1

1

Scipy is not necessary here; drop down to Numpy. argmax() has the behaviour that it returns the index of the first maximum value, in your case 1, over the specified axis. This can be applied in reverse by ::-1 on the second axis for the right-hand case.

import numpy as np

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

left_erode = 101*existing_example_arrayV0
right_erode = left_erode.copy()
y = np.arange(existing_example_arrayV0.shape[0])
left_erode[y, existing_example_arrayV0.argmax(axis=1)] = 1
right_erode[y, -1-existing_example_arrayV0[:, ::-1].argmax(axis=1)] = 1
[[  0   0   1   0   0   0   0]
 [  0   1 101 101   0   0   0]
 [  0   1 101 101 101   0   0]
 [  1 101 101 101 101   0   0]
 [  0   1 101 101 101   0   0]
 [  0   1 101   0   0   0   0]]
[[  0   0   1   0   0   0   0]
 [  0 101 101   1   0   0   0]
 [  0 101 101 101   1   0   0]
 [101 101 101 101   1   0   0]
 [  0 101 101 101   1   0   0]
 [  0 101   1   0   0   0   0]]
Reinderien
  • 11,755
  • 5
  • 49
  • 77
  • Thank you. Would there be a similar methodology instead of left/right, a program that would run top/bottom or bottom/top? – Patstro Jul 16 '23 at 15:45
  • Yes - transpose (`.T`) the array and then run the same code – Reinderien Jul 16 '23 at 15:46
  • is it possible to then add a second iteration where for example in the left iterating code the second maximum number in every row is held constant while values to the right are filled again? – Patstro Jul 18 '23 at 21:32
  • I'm sorry but I don't know what you mean. If you're unable to come up with a solution for that then you should post a new question. – Reinderien Jul 18 '23 at 21:34
  • Let me clarify. Can .argmax return the next value after the maximum. – Patstro Jul 18 '23 at 21:54