16.27. glint_correct¶
The glint_correct program removes sun glint from a visible band
(for example the green band of a WorldView multispectral image) using
the method of Hedley et al. [HHM05]. Glint is the
specular reflection of sunlight from the water surface. It brightens the
water and washes out the submerged features that stereo correlation
needs, so removing it can help bathymetry (Section 8.36).
This is a Python program. It runs in the same bathy conda environment
as bathy_threshold_calc (Section 16.4).
16.27.1. How it works¶
Water is opaque in the near-infrared (NIR), so over water any NIR brightness above a glint-free baseline is due to surface glint, not the bottom. Because the amount of glint in a visible band is proportional to that NIR excess, the corrected band is:
corrected = image - b * (NIR - NIR_min)
The slope b and the baseline NIR_min are found automatically over
optically deep water, which is selected by eroding the water mask inward
from the shore by --deep-water-buffer pixels (so no bottom return
contaminates the fit). Where the NIR equals NIR_min (no glint) the
correction is zero, so glint-free pixels are left unchanged. Only water
pixels are corrected, unless --correct-land is set.
16.27.2. When it helps¶
The correction restores the radiometry of the visible band. The submerged texture that glint had washed out reappears (Fig. 16.7).
Its effect on stereo depends on how strong the glint is. Where glint is strong enough to block matching, removing it recovers a meaningful amount of stereo coverage over water. Where glint is mild, ASP’s correlator already tolerates the one-sided radiometric difference, so the correction adds little and can even reduce coverage slightly, since it lowers the contrast of the water.
Fully saturated glint cannot be recovered at all. The true radiance was lost when the image was acquired.
16.27.3. Example¶
The program takes single-channel inputs. The green (band 3) and NIR (band 7)
of an 8-band WorldView image can be extracted with gdal_translate:
gdal_translate -co TILED=YES -b 3 image.tif green.tif
gdal_translate -co TILED=YES -b 7 image.tif nir.tif
A land-water mask (land = 1, water = 0) on the same grid is also needed. See Section 8.36.3 for how to produce one.
Install the bathy conda environment (Section 16.27.4),
then run:
~/miniconda3/envs/bathy/bin/python $(which glint_correct) \
--image green.tif --nir-image nir.tif --mask mask.tif \
--output-image green_deglint.tif
Here it is assumed that ASP’s bin directory is in the path, otherwise
the full path to this Python script must be specified above.
The corrected band can then be used in stereo in place of the original.
Fig. 16.7 A green band with strong glint (left) and after correction (right). The glint that brightens the lake is removed, restoring the dark water and the submerged detail.¶
16.27.4. Dependencies¶
This tool needs Python 3 with numpy, scipy, matplotlib, and
gdal. These are the same packages as for bathy_threshold_calc.py
(Section 16.4), so its bathy environment can be reused. To
create it, run:
conda create --name bathy -c conda-forge \
python gdal numpy scipy matplotlib
conda activate bathy
16.27.5. Command-line options for glint_correct¶
- -h, --help
Display the help message.
- --image <filename>
The visible band to correct (for example the green band), as a single-channel GeoTIFF.
- --nir-image <filename>
The near-infrared band, as a single-channel GeoTIFF, on the same grid as the visible band.
- --mask <filename>
The land-water mask, as a single-channel GeoTIFF on the same grid, with land = 1 and water = 0.
- --output-image <filename>
The output corrected band. Default: the input image name with a
_deglintsuffix.- --slope <double>
The regression slope. If not set, it is computed over deep water.
- --nir-min <double>
The glint-free NIR baseline. If not set, it is computed over deep water.
- --deep-water-buffer <integer (default: 50)>
Erode the water mask inward by this many pixels to select deep water (free of bottom return) for the regression.
- --nir-min-percentile <double (default: 5)>
Set
NIR_minto this percentile of the deep-water NIR values. A lower value is a more conservative baseline.- --sample-fraction <double (default: 1.0)>
Fraction of deep-water pixels to use in the regression. Reduce for very large scenes.
- --correct-land
Apply the correction to all pixels, not just water.
- --regression-method <ols|theilsen (default: ols)>
Slope estimation method:
ols(ordinary least squares, fast) ortheilsen(median-based, robust to outliers).- --multiband <filenames>
Correct several visible bands at once. Each gets its own slope but they share one
NIR_min. Pass the band GeoTIFFs after this option.- --output-dir <directory (default: deglint)>
Output directory for multiband mode.
- --nodata-value <double>
Output nodata value. Default: inherited from the input band.