msi_processor.computing.coregistration package#
Inter-band co-registration stage (C-PU-COR; DPM-M-COR; ALG-COR-FEAT/HOM/WARP).
Feature-based (CLAHE -> SIFT -> FLANN -> RANSAC homography -> warp) alignment of
the spectral bands to a profile-defined reference band, emitting the co-registered
cor product. The stage is a pure
core plus a thin
CoregistrationUnit wrapper.
Submodules#
msi_processor.computing.coregistration.core module#
Pure inter-band co-registration core (C-PU-COR; ALG-COR-FEAT/HOM/WARP).
CPM-free, I/O-free functions implementing the feature-based inter-band
alignment of ATBD <5.6>, ported faithfully from the heritage band_coreg.py
(BandRegister.shifting_sift; RD-10): each band is 8-bit normalised, contrast
enhanced with CLAHE, SIFT keypoints/descriptors are detected, matched to
the reference band by FLANN with a top-fraction selection, a projective
homography is fitted with RANSAC, and the band is warped to the reference
grid with warpPerspective (ATBD <5.6>; SDD <5.4.6>).
Library policy — this core uses OpenCV. Unlike the radiometric / toa
cores (pure numpy) and the enhancement core (kernels re-implemented in
numpy to avoid scikit-image / PyWavelets), the co-registration
algorithms are defined by OpenCV primitives in the baselined design — SDD
<5.4.6> states “Reuses cv2” and ATBD <5.6> specifies SIFT / FLANN / RANSAC /
warpPerspective by name. Re-implementing scale-invariant feature detection
in numpy would be neither faithful nor maintainable, so opencv is a
genuine runtime dependency of this stage (declared in pyproject.toml; the
headless wheel is used as there is no display in the target/CI runtime).
Radiometry preservation. CLAHE / 8-bit normalisation are applied only to a
throw-away matching surrogate; the homography is then applied to the original
radiometric band (warp_to_reference()), so the output radiometry is the
input radiometry resampled onto the reference grid — never the contrast-stretched
surrogate.
Determinism. RANSAC and the FLANN index draw on OpenCV’s global RNG, which is
seeded from CoregParams.seed before every detection/estimation so re-runs
are reproducible (REQ-F-DEP-02; SDD <5.4.6> error-handling note).
Geometry convention: arrays are 2-D (line|y, detector|x); a homography maps a
band point to the reference point, and shape is the reference (rows, cols)
(ATBD <4.2>, SDD <5.4.6>).
Trace: REQ-F-COR-01..03; DPM-M-COR; ALG-COR-FEAT/HOM/WARP.
- class msi_processor.computing.coregistration.core.CoregParams(reference_band, clahe_clip=2.0, clahe_grid=(8, 8), match_fraction=0.1, min_keypoints=20, min_keypoints_pan=40, pan_bands=(), ransac_tau=5.0, max_residual=None, seed=0)#
Bases:
objectTunable co-registration parameters (SDD <5.4.6>; DPM-PRM-COR-01..04).
- Parameters:
- reference_band:
Profile-defined reference band id every other band is aligned to (
DPM-PRM-COR-01; heritage"b2").- clahe_clip, clahe_grid:
CLAHE clip limit and tile grid for the matching surrogate (
DPM-PRM-COR-02; heritage2.0/(8, 8)).- match_fraction:
Fraction of the FLANN matches, sorted by descriptor distance, retained as tie points (heritage top
0.10).- min_keypoints, min_keypoints_pan:
Minimum SIFT keypoints each image must yield for a band to be matched; the (typically higher-resolution) panchromatic bands listed in
pan_bandsusemin_keypoints_pan(heritage20/40).- pan_bands:
Band ids treated as panchromatic for the keypoint gate. Empty by default; the wrapper populates it from the sensor profile (generic-processor extension of the heritage hard-coded
"b6"rule).- ransac_tau:
RANSAC reprojection-inlier threshold in pixels (heritage
5.0).- max_residual:
Acceptance gate on the inlier RMS reprojection residual in pixels (
DPM-PRM-COR-04, the per-profileBAND_COREGbudget, private).Noneaccepts any solution that has enough inliers.- seed:
Seed for OpenCV’s global RNG (deterministic RANSAC / FLANN, REQ-F-DEP-02).
- Attributes:
- max_residual
Methods
min_keypoints_for(band)Return the keypoint gate for
band(pan-aware).-
clahe_clip:
float= 2.0#
-
clahe_grid:
tuple[int,int] = (8, 8)#
-
match_fraction:
float= 0.1#
-
max_residual:
Optional[float] = None#
-
min_keypoints:
int= 20#
- min_keypoints_for(band)#
Return the keypoint gate for
band(pan-aware).- Return type:
int
-
min_keypoints_pan:
int= 40#
-
pan_bands:
tuple[str,...] = ()#
-
ransac_tau:
float= 5.0#
-
reference_band:
str#
-
seed:
int= 0#
- class msi_processor.computing.coregistration.core.CoregResidual(band, n_inliers, rms_residual_px, accepted)#
Bases:
objectPer-band co-registration outcome (SDD <5.4.6>; ICD-IF-DIAG).
- Parameters:
- band:
Band id the residual refers to (
""until set bycoregister()).- n_inliers:
Number of RANSAC inlier tie points supporting the homography.
- rms_residual_px:
Root-mean-square inlier reprojection residual in pixels.
- accepted:
Whether
rms_residual_pxmetCoregParams.max_residual.
-
accepted:
bool#
-
band:
str#
-
n_inliers:
int#
-
rms_residual_px:
float#
- msi_processor.computing.coregistration.core.coregister(bands, params)#
Co-register every band to the reference band (SDD <5.4.6> pipeline).
For each non-reference band: estimate the homography, check its residual against
CoregParams.max_residual, and warp it onto the reference grid. The reference band passes through unchanged; the stack therefore shares the reference(rows, cols)extent.- Return type:
tuple[dict[str,ndarray[tuple[Any,...],dtype[Any]]],list[CoregResidual]]- Parameters:
- bands:
Mapping of band id to 2-D array; must contain
CoregParams.reference_band.- params:
Co-registration parameters.
- Returns:
- tuple
(registered, residuals)—registeredmaps every band id to its reference-grid array (reference included);residualslists the per-(non-reference-)bandCoregResidualin input order.
- Raises:
- CoregistrationError
If the reference band is absent, or any band fails the keypoint/match gate or its acceptance residual (fail-stop, REQ-F-COR-03) — no misregistered stack is returned.
- msi_processor.computing.coregistration.core.detect_and_match(band, reference, params, *, min_keypoints=None)#
ALG-COR-FEAT — CLAHE-enhanced SIFT detection + FLANN top-fraction matching.
Both images are normalised to 8-bit and CLAHE contrast-enhanced (the matching surrogate only), SIFT keypoints/descriptors are detected, and the band descriptors are matched to the reference by FLANN. Matches are sorted by descriptor distance and the best
CoregParams.match_fractionretained (heritage top 10 %).- Return type:
tuple[ndarray[tuple[Any,...],dtype[float32]],ndarray[tuple[Any,...],dtype[float32]]]- Parameters:
- band, reference:
2-D band and reference arrays,
(line, detector).- params:
Co-registration parameters.
- min_keypoints:
Override for the keypoint gate (defaults to
CoregParams.min_keypoints);coregister()passes the pan-aware value.
- Returns:
- tuple of numpy.ndarray
(src_pts, dst_pts)as(N, 1, 2)float32correspondences,src_ptsin the band frame anddst_ptsin the reference frame.
- Raises:
- CoregistrationError
If either image yields fewer than
min_keypointskeypoints, or fewer than four tie points survive selection (REQ-F-COR-03).
- msi_processor.computing.coregistration.core.estimate_homography(band, reference, params, *, min_keypoints=None)#
ALG-COR-FEAT+HOM — robust homography from band to reference.
Calls
detect_and_match()then fits a \(3\times3\) projective homography \(H\) (band \(\to\) reference) with RANSAC at theCoregParams.ransac_taureprojection threshold, and reports the inlier-RMS residual and its acceptance againstCoregParams.max_residual.- Return type:
tuple[ndarray[tuple[Any,...],dtype[float64]],CoregResidual]- Returns:
- tuple
(H[float64 3x3], CoregResidual); the residual’sbandfield is""here and filled in bycoregister().
- Raises:
- CoregistrationError
On insufficient keypoints/matches (from
detect_and_match()) or if RANSAC cannot fit a model with at least four inliers (REQ-F-COR-03). The acceptance gate itself is not raised here (it is reported viaCoregResidual.accepted);coregister()enforces fail-stop.
- msi_processor.computing.coregistration.core.warp_qa(qa, homography, shape)#
Resample a QA bitmask onto the reference grid (nearest-neighbour).
Companion to
warp_to_reference()forQAFlagmasks: bilinear interpolation would blend bit patterns into meaningless values, so the mask is warped withINTER_NEARESTto preserve exact flag values. Out-of-source pixels become0(the wrapper ORsQAFlag.NO_DATAthere).- Return type:
ndarray[tuple[Any,...],dtype[uint16]]
- msi_processor.computing.coregistration.core.warp_to_reference(band, homography, shape)#
ALG-COR-WARP — resample a band onto the reference grid.
\(I^{\mathrm{reg}}(x',y') = I\big(H^{-1}(x',y')\big)\) via
cv2.warpPerspectivewith bilinear interpolation (heritage). The original radiometric band is warped (radiometry-preserving up to resampling); the input dtype is preserved. Out-of-source pixels are filled with0(their no-data status is recorded in the QA mask by the wrapper).- Return type:
ndarray[tuple[Any,...],dtype[Any]]
msi_processor.computing.coregistration.unit module#
Thin EOProcessingUnit wrapper for inter-band co-registration (C-PU-COR).
Adapts the pure core to the EOPF
CPM runtime following the wrapper template of SDD <5.4.1>/<5.4.6>: read
parameters, extract the input bands, orchestrate the pure-core functions per
band, propagate QA, and build the output cor EOProduct. No algorithm
lives here.
Input convention. The upstream stage is the toa unit; its l1b product
carries the at-sensor radiance under measurements/radiance/<band> (the
feature source and primary measurement), optional TOA reflectance under
measurements/reflectance/<band>, and QA under quality/mask/<band>
(IF-PROD-03). Each non-reference band is aligned to the profile-defined
reference band; the homography estimated from the radiance band is applied to
every co-located representation of that band (radiance and, when present,
reflectance) so the stack stays consistent. The reference band passes through.
This stage takes no ADFs (SDD <5.4.6>): the co-registration parameters (reference band, CLAHE/SIFT/FLANN/RANSAC tuning, acceptance budget) are profile data passed as run parameters, not private calibration content.
Fail-stop (REQ-F-COR-03). On insufficient matches or a residual outside the
acceptance budget, the pure core raises
CoregistrationError carrying the
COREG_FAIL flag; it propagates to the
chain runner so no misregistered product is emitted.
Mandatory inputs are declared by the CPM computing-model JSON
(models/msi_coregistration_1.0.0.json), not by overriding the list methods.
Trace: REQ-F-COR-01..03; DPM-M-COR; ALG-COR-*; ICD IF-PROD-03.
- class msi_processor.computing.coregistration.unit.CoregistrationUnit(identifier='')#
Bases:
EOProcessingUnitInter-band co-registration processing unit (C-PU-COR; SDD <5.4.6>).
- Attributes:
identifierIdentifier of the processing step
Methods
run:
Align every band to the profile-defined reference band and emit the co-registered
corproduct with residual-driven QA.- PROCESSOR_LEVEL = 'L1B'#
- PROCESSOR_MODEL = True#
- PROCESSOR_NAME = 'msi_coregistration'#
- PROCESSOR_VERSION = '1.0.0'#
- run(inputs, adfs=None, mode=None, **kwargs)#
Run the inter-band co-registration.
- Return type:
Mapping[str,Union[EOProduct,EOContainer,DataTree,Iterable[Union[EOProduct,EOContainer,DataTree]]]]- Parameters:
- inputs:
{"l1b": EOProduct}with radiance undermeasurements/radiance, optional reflectance undermeasurements/reflectanceand QA underquality/mask.- adfs:
None (this stage takes no ADFs).
- mode:
"nominal"(the only supported mode).- **kwargs:
CoregParamsfields —reference_band(mandatory),clahe_clip,clahe_grid,match_fraction,min_keypoints,min_keypoints_pan,pan_bands,ransac_tau,max_residual,seed— plus an optionalnamefor the output product.
- Returns:
- Mapping[str, DataType]
{"cor": EOProduct}with the co-registeredmeasurements/radiance/<band>(+measurements/reflectance/<band>when present) and the propagatedquality/mask/<band>.
- Raises:
- CoregistrationError
On insufficient matches or a residual outside acceptance (fail-stop, REQ-F-COR-03).