msi_processor.computing.enhancement package#
Image-quality-enhancement stage (C-PU-ENH; DPM-M-ENH; ALG-ENH-*).
Mandatory Level-1 image-quality restoration: a profile-configurable denoise
sub-step followed by the mandatory MTF compensation (MTFC) via PSF
deconvolution. The stage always runs because MTFC is mandatory (REQ-F-ENH-03).
It is a pure core plus a thin
EnhancementUnit wrapper.
Submodules#
msi_processor.computing.enhancement.core module#
Pure image-quality-enhancement core (C-PU-ENH; ALG-ENH-*).
CPM-free, I/O-free numpy functions implementing the enhancement algorithms
of ATBD <5.4> (configurable denoise) and ATBD <5.5> (mandatory MTF
compensation / PSF deconvolution), ported faithfully from the heritage
level_1.py Denoiser / sharpening classes (RD-10). All arrays are
processed in float32 with a fixed operation order for reproducibility
(REQ-F-DEP-02, REQ-D-05).
Two enhancement sub-steps are provided:
MTF compensation (MTFC) —
mtf_compensate(), the mandatory restoration (ALG-ENH-DECONV). It convolves the band with a profile/ADF-bound PSF-derived deconvolution kernel (heritagesharpening.deconvolution_kernel/cv2.filter2D). Because a low-pass restoration kernel that integrates to one has unit DC gain, the operation is radiometry-preserving (total radiance / mean is conserved) while the high-spatial-frequency content attenuated by the instrument MTF is restored.Denoise —
denoise(), dispatching the profile-configurable sub-step (ALG-ENH-BWLP/WAVE/PCA/MA/GAUSS/FFTDARK). The selector includes"none"so the sub-step can be disabled per sensor; the enhancement stage still always runs because MTFC is mandatory (REQ-F-ENH-03).
Forced deviation from SDD <5.4.4> (libraries). The SDD sketches the denoise
bodies as thin wrappers over skimage / pywt / scikit-image (RD-10).
scikit-image and PyWavelets are not available in the target
runtime (only eopf/numpy/scipy), so — mirroring the
dependency-minimal choice already made for the radiometric and TOA cores (which
re-implement e.g. the NOAA solar position in pure numpy rather than pull a
GPL dependency) — every kernel here is re-implemented in pure numpy:
butterworth_lowpass()— FFT-domain Butterworth low-pass built directly (theskimage.filters.butterworthfrequency response);wavelet_visushrink()— a periodic, orthonormal multilevel Daubechies DWT with VisuShrink soft/hard thresholding (replacingpywt/skimage.restoration.denoise_wavelet);pca_denoise()— low-rank reconstruction vianumpy.linalg.svd()(mathematically identical to the heritagesklearnPCA reconstruction).
Private calibration data (the per-band PSF / MTF and its derived deconvolution
kernel) is never embedded; the kernel is supplied to mtf_compensate()
by the wrapper from the PSF/MTF ADF / sensor profile (REQ-AD-01, REQ-S-01/05).
Geometry convention: arrays are 2-D (line, detector) in focal-plane
geometry (ATBD <4.2>, SDD <5.4.4>).
Trace: REQ-F-ENH-01..03; DPM-M-ENH; ALG-ENH-*.
- class msi_processor.computing.enhancement.core.EnhancementParams(denoise_method='none', denoise_params=<factory>, bit_depth=12, fill_value=None, mtfc_regularization=0.0)#
Bases:
objectTunable enhancement parameters (SDD <5.4.4>; DPM-PRM-ENH-01..05).
- Parameters:
- denoise_method:
Selector for the configurable denoise sub-step (REQ-F-ENH-01).
"none"disables denoising; the enhancement stage still runs because MTF compensation is mandatory (REQ-F-ENH-03).- denoise_params:
Per-method keyword parameters (e.g.
{"cutoff_ratio": 0.2}for Butterworth); all per-band-overridable by the caller.- bit_depth:
Sensor radiometric depth; valid DN range
[0, 2**bit_depth - 1](DPM-PRM-GEN-01, default 12) used byflag_enhanced().- fill_value:
No-data sentinel DN; flagged
QAFlag.NO_DATAwhen present.- mtfc_regularization:
Reserved regularisation strength for the full-deconvolution MTFC mode (Wiener NSR \(K\) / Tikhonov \(\gamma\)); unused by the reference kernel-convolution path, whose regularisation is baked into the profile/ADF kernel (ATBD <5.5>).
- Attributes:
- fill_value
max_dnUpper bound of the valid DN range,
2**bit_depth - 1.
-
bit_depth:
int= 12#
-
denoise_method:
Literal['none','butterworth','wavelet','pca','moving_average','gaussian','fft_dark'] = 'none'#
-
denoise_params:
Mapping[str,Any]#
-
fill_value:
Optional[float] = None#
- property max_dn: int#
Upper bound of the valid DN range,
2**bit_depth - 1.
-
mtfc_regularization:
float= 0.0#
- msi_processor.computing.enhancement.core.butterworth_lowpass(image, cutoff_ratio=0.2, order=10.0, squared=False, npad=0)#
ALG-ENH-BWLP — frequency-domain Butterworth low-pass denoise.
Re-implements the
skimage.filters.butterworthlow-pass response in purenumpy(heritageDenoiser.get_filtered_butterworth): :rtype:ndarray[tuple[Any,...],dtype[float32]]\[W(\mathbf q) = \Big(1 + (\lVert \mathbf q\rVert / f_c)^{2n}\Big)^{-s},\]with \(s = 1\) for
squaredand \(s = 1/2\) otherwise,f_c=cutoff_ratioandn=order. Because \(W(\mathbf 0) = 1\) the DC term is preserved, so the band mean is conserved (radiometry-preserving) while high frequencies (noise) are attenuated.npadedge-pads the band before the FFT to mitigate boundary ringing (Gibbs). Returnsfloat32.
- msi_processor.computing.enhancement.core.denoise(image, method, params, dark=None)#
Dispatch to the selected denoiser (heritage
Denoiser.*).- Return type:
ndarray[tuple[Any,...],dtype[float32]]- Parameters:
- image:
Input band, dims
(line, detector).- method:
One of
DenoiseMethod."none"returns the band unchanged (the configurable sub-step disabled, REQ-F-ENH-01).- params:
Per-method keyword parameters (see each kernel’s defaults).
- dark:
Dark reference frame, required only for
"fft_dark".
- Returns:
- numpy.ndarray
The denoised band as
float32. Range clipping to the valid DN interval is centralised inflag_enhanced().
- msi_processor.computing.enhancement.core.fft_dark_subtract(image, dark)#
ALG-ENH-FFTDARK — FFT-domain dark-pattern subtraction denoise. :rtype:
ndarray[tuple[Any,...],dtype[float32]]\[\hat I = \Re\big\{\mathcal F^{-1}(\mathcal F(I) - \mathcal F(D))\big\}\](heritage
Denoiser.dark_noise_removal). By linearity of the Fourier transform this equals the spatial dark subtraction \(I - D\); the FFT route is retained where a frequency-selective dark notch is desired (cf. the radiometricremove_dark_fft). The dark frame is cropped to the band extent and negative results are floored at 0. Returnsfloat32.
- msi_processor.computing.enhancement.core.flag_enhanced(image, params)#
Clip to the valid range and flag saturation / no-data (SDD <5.4.4>).
The enhanced band is clipped to
[0, 2**bit_depth - 1](REQ-D-05); samples at or above the ceiling — e.g. MTFC restoration overshoot — are flaggedQAFlag.SATURATED; non-finite samples and any equal toparams.fill_valueare flaggedQAFlag.NO_DATA. Mirrors the radiometricflag_saturationcontract.- Return type:
tuple[ndarray[tuple[Any,...],dtype[float32]],ndarray[tuple[Any,...],dtype[uint16]]]- Returns:
- tuple of numpy.ndarray
(clipped[float32], qa[uint16])of the same shape asimage.
- msi_processor.computing.enhancement.core.gaussian_smooth(image, ksize=5, sigma=None)#
ALG-ENH-GAUSS — separable Gaussian-blur denoise.
Convolves the band with a normalised, separable 2-D Gaussian of window
ksize(heritageDenoiser.gaussian_filter_ips,cv2.GaussianBlur). WhensigmaisNoneit defaults to the band standard deviation (the heritage choice). The kernel integrates to one, so the band mean is conserved (radiometry-preserving); a degenerate \(\sigma \le 0\) returns the band unchanged. Returnsfloat32.- Return type:
ndarray[tuple[Any,...],dtype[float32]]
- msi_processor.computing.enhancement.core.moving_average(image, n=60)#
ALG-ENH-MA — along-track \((2N+1)\) sliding-mean denoise.
The canonical centred sliding mean over the line (along-track) axis adopted by
msi-processorin place of the heritage row-block-to-scalar reduction (ATBD <5.4>): :rtype:ndarray[tuple[Any,...],dtype[float32]]\[\hat I_{l,d} = \frac{1}{|\mathcal W_l|}\sum_{l'\in\mathcal W_l} I_{l',d}, \qquad \mathcal W_l = [l-N,\,l+N] .\]The window is truncated (and the mean re-normalised by the available count) at the array borders, so a flat band is preserved exactly everywhere. Returns
float32.
- msi_processor.computing.enhancement.core.mtf_compensate(image, psf_kernel)#
ALG-ENH-DECONV — MTF compensation (MTFC) via PSF deconvolution.
The mandatory Level-1 restoration. The band is filtered with the profile/ADF-bound, PSF-derived spatial deconvolution kernel \(k\) (heritage
sharpening.deconvolution_kernel/cv2.filter2D): :rtype:ndarray[tuple[Any,...],dtype[float32]]\[\hat I = I \star k ,\]a cross-correlation with periodic (wrap-around) boundary handling. The kernel is the spatial-domain image of a regularised inverse of the system PSF (Wiener / Tikhonov / Richardson-Lucy candidate, down-selected per sensor; ATBD <5.5>), broader for the higher-resolution (panchromatic) band.
Notes
The kernel is supplied by the caller from the PSF/MTF ADF and is never embedded here (REQ-AD-01). A restoration kernel that integrates to one has unit DC gain, so the global radiance (mean) is conserved — the restoration is radiometry-preserving. Final clipping to the valid DN range is deferred to
flag_enhanced()(mirroring thedn_to_radiance/flag_radiancesplit of the TOA core). Returnsfloat32.
- msi_processor.computing.enhancement.core.pca_denoise(image, n_components)#
ALG-ENH-PCA — low-rank PCA reconstruction denoise.
Mathematically identical to the heritage
sklearnPCA fit / inverse transform, re-expressed via the (economy) SVD of the column-centred band: with \(X = \bar X + U\Sigma V^{\!\top}\) the rank-\(k\) reconstruction \(\hat X = \bar X + U_k\Sigma_k V_k^{\!\top}\) discards the low-variance (noise) subspace. Rows are samples and columns features, as in the heritage code.n_componentsis clamped to[1, min(line, detector)]. A flat band (zero centred residual) is preserved exactly. Returnsfloat32.- Return type:
ndarray[tuple[Any,...],dtype[float32]]
- msi_processor.computing.enhancement.core.wavelet_visushrink(image, wavelet='db3', levels=20, sigma_scale=0.3333333333333333, mode='soft')#
ALG-ENH-WAVE — VisuShrink wavelet denoise (periodic Daubechies DWT).
Re-implements
skimage.restoration.denoise_wavelet(method="VisuShrink") in purenumpy(heritageDenoiser.wavelet_denoising_cdk): a multilevel orthonormal Daubechies decimated DWT with periodic boundary, MAD noise estimation and universal-threshold shrinkage of every detail band.The noise level is estimated from the finest diagonal detail band, \(\hat\sigma = \mathrm{median}(|d_{HH}^{(1)}|)/0.6745\), and the universal threshold is \(\lambda = s\,\hat\sigma\sqrt{2\ln N}\) with
sigma_scale\(s\) and \(N\) the pixel count. Detail coefficients are soft- or hard-thresholded; the coarse approximation is left intact. A flat band has zero detail energy, so it is preserved exactly (up to float round-off). Returnsfloat32.- Return type:
ndarray[tuple[Any,...],dtype[float32]]
Notes
The number of levels is capped at the largest depth for which both axes stay even and no shorter than the filter (so the periodic transform stays orthonormal / perfectly reconstructing).
msi_processor.computing.enhancement.unit module#
Thin EOProcessingUnit wrapper for image-quality enhancement (C-PU-ENH).
Adapts the pure core to the EOPF
CPM runtime following the wrapper template of SDD <5.4.1>/<5.4.4>: read
parameters, extract input bands, load/validate ADFs, call the core per band,
propagate QA, and build the output enh EOProduct. No algorithm lives
here.
The enhancement stage always runs (REQ-F-ENH-03): the mandatory MTF
compensation (mtf_compensate())
is applied to every band, optionally preceded by the profile-configurable
denoise sub-step. The denoise sub-step is disabled by selecting
denoise_method="none"; the stage still executes because MTFC is mandatory.
Mandatory inputs/ADFs are declared by the CPM computing-model JSON
(models/msi_enhancement_1.0.0.json), not by overriding the list methods.
Input convention. The upstream stage is the mandatory radiometric unit; its
rad product carries corrected DN under measurements/detector/<band> and
QA under quality/mask/<band> (IF-PROD-02). The enh output keeps the same
shape so it can feed the downstream toa unit unchanged.
ADF data convention (this increment). The unit reads ADF content from the
AuxiliaryDataFile.data_ptr mapping (the CPM data_ptr is documented as
holding the opened data):
psf->{"kernel": {band: ndarray2d}}(mandatory; the per-band PSF-derived deconvolution kernel for MTFC, ATBD <5.5>). Deviation note: the SDD <5.4.4> computing-model JSON sketch lists only the optionaldarkADF, but MTFC is mandatory and consumes a PSF/MTF kernel, so the kernel ADF is declared mandatory here (per the C-PU-ENH task brief). Private kernel content is supplied via this ADF and never embedded (REQ-AD-01).dark->{"frame": {band: ndarray2d}}(optional; required only whendenoise_method="fft_dark"), matching the radiometricdarkADF shape.
Trace: REQ-F-ENH-01..03; DPM-M-ENH; ALG-ENH-*; ICD IF-PROD-02.
- class msi_processor.computing.enhancement.unit.EnhancementUnit(identifier='')#
Bases:
EOProcessingUnitImage-quality-enhancement processing unit (C-PU-ENH; SDD <5.4.4>).
- Attributes:
identifierIdentifier of the processing step
Methods
run:
Apply the optional denoise sub-step and the mandatory MTF compensation to every band and emit the
enhproduct.- PROCESSOR_LEVEL = 'L1B'#
- PROCESSOR_MODEL = True#
- PROCESSOR_NAME = 'msi_enhancement'#
- PROCESSOR_VERSION = '1.0.0'#
- run(inputs, adfs=None, mode=None, **kwargs)#
Run the image-quality enhancement.
- Return type:
Mapping[str,Union[EOProduct,EOContainer,DataTree,Iterable[Union[EOProduct,EOContainer,DataTree]]]]- Parameters:
- inputs:
{"rad": EOProduct}with bands undermeasurements/detectorand optional QA underquality/mask.- adfs:
psf(mandatory; per-band MTFC deconvolution kernel);dark(optional; required only fordenoise_method="fft_dark").- mode:
"nominal"(the only supported mode); the stage always runs.- **kwargs:
EnhancementParamsfields (denoise_method,denoise_params,bit_depth,fill_value,mtfc_regularization); optionalnamefor the output product.
- Returns:
- Mapping[str, DataType]
{"enh": EOProduct}with the MTFC-restored (optionally denoised) DN undermeasurements/detector/<band>and the propagated QA underquality/mask/<band>.