Binary morphology#
healpix-analyse provides binary mathematical morphology for masks
represented by active nested HEALPix cell IDs.
The initial API consists of:
from healpix_analyse.morphology import (
binary_dilation,
binary_erosion,
)
Structuring neighbourhoods#
On a regular Cartesian raster, a disk-shaped structuring element is usually defined by a pixel-centre distance criterion:
[ \sqrt{\Delta x^2 + \Delta y^2} \le r. ]
HEALPix does not have a fixed two-dimensional Cartesian neighbourhood.
Instead, healpix-analyse defines the structuring neighbourhood
geometrically.
Two definitions are available.
Cell-centre neighbourhood#
neighbourhood="cell_center"
A HEALPix cell \(q\) is included around a target cell \(p\) when
[ d_{\mathrm{WGS84}} \left( \operatorname{center}(p), \operatorname{center}(q) \right) \le r. ]
Here, radius is specified in metres.
This is the default neighbourhood because it most closely reproduces the semantics of a classical disk-shaped raster structuring element: membership is determined from the distance between cell centres.
Example:
dilated = binary_dilation(
cells,
radius=240.0,
refinement_level=17,
neighbourhood="cell_center",
)
Cone-coverage neighbourhood#
neighbourhood="cone_coverage"
This alternative uses:
healpix_geo.nested.cone_coverage()
and includes HEALPix cells intersecting the requested circular region.
Therefore, a cell may be included even when its centre lies outside the requested radius.
Conceptually:
cell_center
o cell centre outside
-----------------
/ \
/ radius \
| C |
\ /
-----------------
Only cells whose centres are inside the circle are selected.
cone_coverage
+-------+
| o | cell centre outside
----|-------|----
/ | | \
/ +-------+ \
| C |
\ /
-----------------
The cell is also selected because it intersects the circle.
As a consequence,
cell_center neighbourhood ⊆ cone_coverage neighbourhood
for the same target cell and radius.
Sentinel-2 MSI Mask S2 example#
The original raster parameters are:
Operation |
Raster radius |
Nominal physical radius |
|---|---|---|
Cloud erosion |
3 pixels |
180 m |
Snow dilation |
4 pixels |
240 m |
Cloud dilation |
8 pixels |
480 m |
For a HEALPix implementation, the physical radii can be preserved directly.
HEALPix refinement level 17 is close to the spatial scale of the 60 m Mask S2 processing grid.
For example:
snow = binary_dilation(
snow_cells,
radius=240.0,
refinement_level=17,
neighbourhood="cell_center",
)
opaque = binary_erosion(
opaque_cells,
radius=180.0,
refinement_level=17,
neighbourhood="cell_center",
)
opaque = binary_dilation(
opaque,
radius=480.0,
refinement_level=17,
neighbourhood="cell_center",
)
The same applies to the cirrus mask.
Difference between the two neighbourhood definitions#
A regression test using a single HEALPix cell at refinement level 17 gives:
Radius |
|
|
Additional coverage cells |
|---|---|---|---|
180 m |
41 |
63 |
22 |
240 m |
73 |
99 |
26 |
480 m |
295 |
339 |
44 |
The larger values from cone_coverage are expected.
cell_center selects cells according to their centre-to-centre
distance, whereas cone_coverage also includes cells whose centres
are outside the circle but whose cell area intersects it.
For reproducing the S2MSI disk structuring-element semantics,
cell_center is therefore the recommended/default method.
Processing domains#
Binary masks are represented by their active HEALPix cell IDs.
For regional datasets such as Sentinel-2 tiles, an optional domain
can specify all HEALPix cells over which the mask is defined.
eroded = binary_erosion(
cells,
radius=180.0,
refinement_level=17,
neighbourhood="cell_center",
domain=domain_cells,
)
When a domain is supplied:
inactive cells inside the domain are interpreted as
False;cells outside the domain are outside the processing extent;
dilation is clipped to the domain;
erosion ignores structuring-neighbourhood cells outside the domain.
This prevents artificial erosion along the edge of a regional dataset.