Skip to content

morphology: centre-cell leak in erode/dilate when kernel[centre]==0 #1397

@brendancol

Description

@brendancol

Describe the bug

morph_erode and morph_dilate seed the running min/max from the centre cell before the kernel loop runs. When the kernel has a 0 at the centre (the centre is excluded from the structuring element footprint), the loop correctly skips the centre cell, but the seed already came from it. The centre value contaminates the result.

Affects all four backends:

  • _erode_kernel_numpy (xrspatial/morphology.py:133-159), line 145 seeds mn = val
  • _dilate_kernel_numpy (xrspatial/morphology.py:162-188), line 174 seeds mx = val
  • _erode_gpu (xrspatial/morphology.py:230-253), line 240
  • _dilate_gpu (xrspatial/morphology.py:256-279), line 266

Reproducer

import numpy as np, xarray as xr
from xrspatial.morphology import morph_erode, morph_dilate

# Cross-with-hole kernel: centre excluded
kernel = np.array([[1,1,1],[1,0,1],[1,1,1]], dtype=np.uint8)

# Erosion: centre is the local minimum, neighbours are all 5
data = np.full((5, 5), 5.0)
data[2, 2] = 1.0
agg = xr.DataArray(data)
print(morph_erode(agg, kernel=kernel, boundary='nearest').data[2, 2])
# Expected: 5.0  (centre excluded; all 8 neighbours are 5.0)
# Actual:   1.0  (centre value leaked in)

# Dilation: centre is the local maximum
data2 = np.full((5, 5), 5.0)
data2[2, 2] = 100.0
agg2 = xr.DataArray(data2)
print(morph_dilate(agg2, kernel=kernel, boundary='nearest').data[2, 2])
# Expected: 5.0
# Actual:   100.0

Expected behavior

When kernel[centre] == 0, the centre cell should not influence the output. Only kernel-included neighbours should contribute to the local min/max.

Fix

Skip the centre seed. Assign from the first kernel-included neighbour, then compare against subsequent ones. Keep existing NaN-propagation semantics.

Categories

Off-by-one / structuring-element semantics. Affects numpy, cupy, dask+numpy, dask+cupy backends.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfocal toolsFocal statistics and hotspot analysishigh-priority

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions