Patstro
Patstro

Reputation: 69

Erosion and Dilation of Image in one direction using Scipy

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

Upvotes: 1

Views: 198

Answers (1)

Reinderien
Reinderien

Reputation: 15231

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

Upvotes: 2

Related Questions