Image Classifier (NavImageClassifier)
Overview
NavImageClassifier is the quick-fail image
quality classifier the orchestrator runs once per image before any
NavModel is constructed.
It assigns the image to one of a small set of classes (clean /
blank / fully_overexposed / mostly_missing_data) plus optional advisory flags
(noisy / partial_dropout). The hard-failure classes short-circuit the pipeline
inside NavOrchestrator — corrupted or blank
images fail in milliseconds with a clear status reason.
Theory
The classifier evaluates three cheap statistics over the sensor pixels:
saturation_frac— fraction of pixels at or above the per-instrument saturation DN.missing_frac— fraction of pixels matching the per-instrument missing-data marker: pixels exactly equal to the marker DN, or, when the marker is itselfNaN(calibrated-IF dropout), pixels for whichnp.isnanholds.noise_sigma— robust MAD-based noise sigma over the sensor area.
The decision tree is order-sensitive:
Blank check first. When the maximum sensor DN is below
blank_max_dn, the image isblank. The blank check fires before the missing-fraction test so a near-zero image whose missing-data marker is also zero is not mis-classified asmostly_missing_data.Fully overexposed. When the saturation fraction exceeds
max_saturation_frac_clean(default 0.80), the image isfully_overexposed.Mostly missing data. When the missing fraction exceeds
max_missing_frac_clean(default 0.30), the image ismostly_missing_data.Clean. Otherwise the image is
clean. Two advisory flags may attach:partial_dropoutwhen the missing fraction sits betweenpartial_dropout_min_fracandmax_missing_frac_clean;noisywhen the noise sigma exceedsnoisy_threshold.
The orchestrator’s _HARD_FAILURE_TO_REASON dispatch table maps the three hard-failure
classes to
NavStatusReason values; the clean case proceeds
through the pipeline regardless of the advisory flags.
Restrictions and assumptions
The classifier assumes the per-instrument thresholds are calibrated correctly. An
ImageQualityThresholdsconfigured for a different instrument will mis-classify exposures.The classifier reads pixel statistics over the sensor mask only; extfov padding is excluded. When the caller passes
sensor_mask=Noneevery pixel is treated as sensor data.The matched-filter detection in star navigation consumes a separate noise-sigma estimate from
estimate_image_noise_sigma(); the classifier’snoise_sigmais the same MAD estimator but on the per-image sensor cohort.The classifier does not look at predicted feature positions — it is a global readout over the whole sensor, not a per-target check.
Sources of uncertainty
The classifier reports no uncertainty. Its outputs (the verdict and the three statistics) are deterministic functions of the input image and the configured thresholds.
Configuration
Per-instrument thresholds live in
ImageQualityThresholds, populated by
instrument_settings_from_obs() from the
image_quality_thresholds block in config_4N0_inst_*.yaml. Documented at
Per-Instrument Settings (InstrumentSettings).
The thresholds dataclass:
saturation_threshold_dn— float, default4095.0DN. Pixels at or above this DN are flagged saturated.missing_data_marker_dn— float, default0.0DN. Pixels exactly equal to this value are missing data; when the marker isNaN, the classifier detects missing data vianp.isnaninstead.max_saturation_frac_clean— float, default0.80(dimensionless). Above this fraction of saturated pixels the image isfully_overexposed.max_missing_frac_clean— float, default0.30(dimensionless). Above this fraction of missing pixels the image ismostly_missing_data.partial_dropout_min_frac— float, default0.05(dimensionless). At or above this fraction (and belowmax_missing_frac_clean) thepartial_dropoutadvisory flag is set.blank_max_dn— float, default5.0DN. Below this maximum sensor DN the image isblank.noisy_threshold— float, default10.0DN. Above this MAD-noise sigma thenoisyadvisory flag is set.
Implementation
Source files:
src/nav/nav_orchestrator/image_classifier.py—NavImageClassifierandImageQualityThresholds.src/nav/nav_orchestrator/image_classifier_result.py—NavImageClassifierResultplus theImageClassandImageFlagLiteral aliases.src/nav/support/noise_estimate.py—estimate_image_noise_sigma(), the MAD-based noise estimator the classifier delegates to.
Public classes (autodocumented at nav.nav_orchestrator):
NavImageClassifier— the classifier. Public method:classify()runs the three-statistic readout plus the decision tree and returns aNavImageClassifierResult.ImageQualityThresholds— frozen dataclass carrying the seven thresholds documented above.NavImageClassifierResult— frozen dataclass returned byclassify. Public fields:image_class,saturation_frac,missing_frac,noise_sigma,max_dn,flags.
Examples
Clean Cassini calibration target. Saturation fraction 0.0, missing fraction 0.0, max DN 4000, MAD sigma 4.7. Verdict:
NavImageClassifierResult(
image_class='clean',
saturation_frac=0.0,
missing_frac=0.0,
noise_sigma=4.7,
max_dn=4000.0,
flags=[],
)
Blank image after a failed integration. Maximum DN 2.1. The blank check fires first:
NavImageClassifierResult(
image_class='blank',
saturation_frac=0.0,
missing_frac=0.62, # the missing-data marker was 0
noise_sigma=0.4,
max_dn=2.1,
flags=[],
)
The orchestrator’s hard-failure short-circuit maps image_class='blank' to
NO_SIGNAL_IN_IMAGE and returns a failed
NavResult before any
NavModel constructs.
Clean with advisory flags. Saturation fraction 0.0, missing fraction 0.12, MAD sigma 12.4. The classifier reports:
NavImageClassifierResult(
image_class='clean',
saturation_frac=0.0,
missing_frac=0.12,
noise_sigma=12.4,
max_dn=3800.0,
flags=['partial_dropout', 'noisy'],
)
The orchestrator proceeds through the pipeline; the advisory flags surface in the per-image JSON sidecar so reviewer tooling can correlate noisy / partially-dropped scenes across a campaign.