{ "schema": "multispec_module_params_v3", "saved_at": "2026-05-08 09:23:01", "frame_type": "RAW_BRUTO", "capture_mode_requested": "AUTO", "capture_mode_effective": "AUTO", "raw_policy": "allow_single", "sensor_width": 1280, "sensor_height": 800, "bayer_pattern": "RGGB", "camera_settings": { "rgb": { "ae_enable": false, "awb_enable": false, "exposure_time_us": 2000, "analogue_gain": 1.0, "colour_gains": [ 1.0, 1.0 ] }, "re": { "ae_enable": false, "awb_enable": false, "exposure_time_us": 5000, "analogue_gain": 1.0, "colour_gains": null }, "nir": { "ae_enable": false, "awb_enable": false, "exposure_time_us": 5000, "analogue_gain": 1.0, "colour_gains": null } }, "fusion_config": { "alignment_mode": "homography", "baseline_mm": 75.0, "reference_camera": "rgb", "manual_offsets": { "re": { "dx": 0, "dy": 0, "theta_deg": 0.0 }, "nir": { "dx": 0, "dy": 0, "theta_deg": 0.0 } }, "homographies": { "re_to_rgb": [ [ 0.9891488988352489, -0.0057973762346762115, -15.173511767385348 ], [ -0.015114489970267686, 0.9903282034674085, 58.93120393758602 ], [ -2.1528138783460464e-05, -1.5606269505459822e-05, 1.0 ] ], "nir_to_rgb": [ [ 1.015255211995985, -0.011641307565439515, -15.440297021288165 ], [ 0.006224807373165827, 1.0059040970450264, 21.05815660535078 ], [ 5.830335800966281e-06, -1.5297165752796802e-05, 1.0 ] ] }, "crop_valid_common": true, "resize_after_crop": true, "target_size": null }, "radiometric_config": { "enabled": true, "interval_s": 0.25, "verbose": true, "metering_mode": "reference_patches", "spectral_control_mode": "independent", "control_metric": "p50", "target_value": 0.5, "deadband": 0.035, "p95_limit": 0.94, "saturation_limit_pct": 0.5, "alpha": 0.18, "exp_step_gain": 0.55, "prefer_exposure": true, "exp_min_us": 100, "exp_max_us": 80000, "gain_min": 1.0, "gain_max": 4.0, "reference_patches": [ { "name": "black_reference", "type": "black", "roles": [ "rgb", "re", "nir" ], "roi_pct": { "x0": 0.365625, "y0": 0.8225, "x1": 0.432812, "y1": 0.995 }, "target_value": 0.08, "weight": 0.7, "roi_pct_by_role": { "rgb": { "x0": 0.365625, "y0": 0.8225, "x1": 0.432812, "y1": 0.995 }, "re": { "x0": 0.395313, "y0": 0.745, "x1": 0.4625, "y1": 0.9225 }, "nir": { "x0": 0.353125, "y0": 0.78, "x1": 0.420312, "y1": 0.9525 } }, "roi_list_by_role": { "rgb": [ { "name": "rgb_legacy_01", "enabled": true, "roi_pct": { "x0": 0.365625, "y0": 0.8225, "x1": 0.432812, "y1": 0.995 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:19:46" } ], "re": [ { "name": "re_legacy_01", "enabled": true, "roi_pct": { "x0": 0.395313, "y0": 0.745, "x1": 0.4625, "y1": 0.9225 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:20:14" } ], "nir": [ { "name": "nir_legacy_01", "enabled": true, "roi_pct": { "x0": 0.353125, "y0": 0.78, "x1": 0.420312, "y1": 0.9525 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:20:47" } ] } }, { "name": "gray_reference", "type": "gray", "roles": [ "rgb", "re", "nir" ], "roi_pct": { "x0": 0.29375, "y0": 0.825, "x1": 0.3625, "y1": 0.995 }, "target_value": 0.35, "target_value_by_role": { "rgb": 0.34, "re": 0.24, "nir": 0.3 }, "weight": 1.0, "roi_pct_by_role": { "rgb": { "x0": 0.29375, "y0": 0.825, "x1": 0.3625, "y1": 0.995 }, "re": { "x0": 0.325, "y0": 0.75, "x1": 0.389062, "y1": 0.915 }, "nir": { "x0": 0.284375, "y0": 0.79, "x1": 0.35, "y1": 0.9525 } }, "roi_list_by_role": { "rgb": [ { "name": "rgb_legacy_01", "enabled": true, "roi_pct": { "x0": 0.29375, "y0": 0.825, "x1": 0.3625, "y1": 0.995 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:19:29" } ], "re": [ { "name": "re_legacy_01", "enabled": true, "roi_pct": { "x0": 0.325, "y0": 0.75, "x1": 0.389062, "y1": 0.915 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:20:22" } ], "nir": [ { "name": "nir_legacy_01", "enabled": true, "roi_pct": { "x0": 0.284375, "y0": 0.79, "x1": 0.35, "y1": 0.9525 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:20:53" } ] } }, { "name": "white_reference", "type": "white", "roles": [ "rgb", "re", "nir" ], "roi_pct": { "x0": 0.220312, "y0": 0.8225, "x1": 0.2875, "y1": 0.995 }, "target_value": 0.82, "weight": 0.8, "roi_pct_by_role": { "rgb": { "x0": 0.220312, "y0": 0.8225, "x1": 0.2875, "y1": 0.995 }, "re": { "x0": 0.25, "y0": 0.7525, "x1": 0.315625, "y1": 0.9225 }, "nir": { "x0": 0.214062, "y0": 0.785, "x1": 0.282813, "y1": 0.9525 } }, "roi_list_by_role": { "rgb": [ { "name": "rgb_legacy_01", "enabled": true, "roi_pct": { "x0": 0.220312, "y0": 0.8225, "x1": 0.2875, "y1": 0.995 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:19:04" } ], "re": [ { "name": "re_legacy_01", "enabled": true, "roi_pct": { "x0": 0.25, "y0": 0.7525, "x1": 0.315625, "y1": 0.9225 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:20:27" } ], "nir": [ { "name": "nir_legacy_01", "enabled": true, "roi_pct": { "x0": 0.214062, "y0": 0.785, "x1": 0.282813, "y1": 0.9525 }, "created_at": "2026-05-07 14:36:25", "updated_at": "2026-05-08 09:21:02" } ] } } ], "exp_apply_threshold_us": 80, "gain_apply_threshold": 0.05, "apply_same_spectral_to_both": false, "spectral_roles": [ "re", "nir" ], "dark_limit_pct": 35.0, "control_strategy": "ratio", "ratio_alpha": 0.35, "ratio_min": 0.65, "ratio_max": 1.35, "reduce_fast_factor": 0.8, "factor_min": 0.55, "factor_max": 1.28, "gain_return_enabled": true, "gain_reduce_on_saturation": true, "gain_increase_required_cycles": 5, "gain_decrease_required_cycles": 2, "gain_step_up": 0.2, "gain_step_down": 0.5, "gain_hard_reset_on_saturation": false, "exp_high_ratio_for_gain": 0.95, "exp_low_ratio_for_gain_return": 0.75, "role_limits": { "rgb": { "exp_min_us": 100, "exp_max_us": 80000, "gain_min": 1.0, "gain_max": 2.0 }, "re": { "exp_min_us": 100, "exp_max_us": 2500, "gain_min": 1.0, "gain_max": 2.0 }, "nir": { "exp_min_us": 100, "exp_max_us": 3000, "gain_min": 1.0, "gain_max": 2.0 } }, "ready_required_cycles": 3, "patch_control_mode": "gray_primary", "patch_require_order": true, "patch_min_separation": 0.08, "patch_white_sat_limit_pct": 0.5, "patch_white_p95_limit": 0.94, "patch_black_dark_limit_pct": 80.0, "patch_black_max_p50": 0.2, "patch_gray_min_p50": 0.08, "patch_gray_max_p50": 0.85, "patch_roi_contract": "multi_roi_by_role_v1", "patch_roi_reduce_method": "median_valid_rois", "patch_roi_outlier_reject": true, "patch_roi_max_p50_delta": 0.12, "global_saturation_guard_enabled": true, "global_guard_roi_pct": { "x0": 0.05, "y0": 0.05, "x1": 0.95, "y1": 0.95 }, "global_guard_sat_threshold": 0.985, "global_guard_near_sat_threshold": 0.94, "global_guard_sat_pct_soft": 0.05, "global_guard_sat_pct_hard": 0.2, "global_guard_sat_pct_extreme": 0.8, "global_guard_blob_pct_soft": 0.015, "global_guard_blob_pct_hard": 0.08, "global_guard_blob_pct_extreme": 0.25, "global_guard_min_blob_px": 48, "global_guard_downsample_max_side": 320, "global_guard_reduce_factor_soft": 0.82, "global_guard_reduce_factor_hard": 0.6, "global_guard_reduce_factor_extreme": 0.35, "sun_guard_enabled": true, "sun_guard_p99_threshold": 0.9, "sun_guard_near_sat_pct_threshold": 0.8, "sun_guard_freeze_increase_cycles": 2, "sun_guard_allow_decrease": true, "guard_force_apply_enabled": true, "guard_force_apply_soft": true, "guard_force_apply_hard": true, "guard_force_apply_extreme": true, "guard_force_apply_on_patch_saturation": true, "guard_freeze_cycles_soft": 3, "guard_freeze_cycles_hard": 5, "guard_freeze_cycles_extreme": 8, "guard_reapply_min_exp_on_emergency": true, "guard_min_exp_margin_us": 80 }, "radiometric_normalization": { "enabled": false, "method": "exposure_gain_reference", "apply_stage": "after_dark_before_flat_gain", "reference_controls": { "rgb": { "exposure_time_us": 3000, "analogue_gain": 1.0 }, "re": { "exposure_time_us": 7000, "analogue_gain": 1.0 }, "nir": { "exposure_time_us": 7000, "analogue_gain": 1.0 } }, "clip_output": true }, "patch_normalization": { "enabled": true, "apply_when_metering_mode": "reference_patches", "apply_stage": "after_fusion", "method": "gray_scale_with_white_guard", "space": "multispec_tensor", "targets": { "black": 0.06, "gray": 0.4, "white": 0.78 }, "white_guard_max": 0.92, "scale_min": 0.35, "scale_max": 2.5, "clip_output": true, "require_valid_gray": true, "use_black_for_offset": false, "save_patch_stats": true }, "rgb_calibration": { "enabled": true, "gains": { "R": 1.2500000000000002, "G": 1.0, "B": 1.5500000000000005 } }, "flatfield_config": { "enabled": false, "subtract_dark": true, "schema": "multispec_flatfield_v1", "created_at": "2026-05-06 13:37:25", "json_file": "calibration/flatfield_maps_v1.json", "npz_file": "calibration/flatfield_maps_v1.npz", "apply_before_fusion": true, "apply_after_decode": true, "apply_space": "native_camera_space", "map_type": "gain", "formula": "channel_corrected = max(channel_linear - dark, 0) * gain_map", "channels": [ "R", "G", "B", "RE", "NIR" ], "channel_maps": { "R": { "gain_key": "gain_R", "flat_norm_key": "flat_norm_R", "white_median_key": "white_median_R", "dark_median_key": "dark_median_R", "shape": [ 400, 640 ], "gain_min": 0.5639018416404724, "gain_max": 1.8886771202087402, "gain_mean": 1.0681155920028687, "gain_std": 0.3506295084953308 }, "G": { "gain_key": "gain_G", "flat_norm_key": "flat_norm_G", "white_median_key": "white_median_G", "dark_median_key": "dark_median_G", "shape": [ 400, 640 ], "gain_min": 0.5427238941192627, "gain_max": 2.177884101867676, "gain_mean": 1.0985527038574219, "gain_std": 0.4235461354255676 }, "B": { "gain_key": "gain_B", "flat_norm_key": "flat_norm_B", "white_median_key": "white_median_B", "dark_median_key": "dark_median_B", "shape": [ 400, 640 ], "gain_min": 0.57332444190979, "gain_max": 1.991808533668518, "gain_mean": 1.0765669345855713, "gain_std": 0.36871764063835144 }, "RE": { "gain_key": "gain_RE", "flat_norm_key": "flat_norm_RE", "white_median_key": "white_median_RE", "dark_median_key": "dark_median_RE", "shape": [ 800, 1280 ], "gain_min": 0.7719405889511108, "gain_max": 1.6437114477157593, "gain_mean": 1.0222759246826172, "gain_std": 0.19225353002548218 }, "NIR": { "gain_key": "gain_NIR", "flat_norm_key": "flat_norm_NIR", "white_median_key": "white_median_NIR", "dark_median_key": "dark_median_NIR", "shape": [ 800, 1280 ], "gain_min": 0.808167576789856, "gain_max": 1.5716955661773682, "gain_mean": 1.021193265914917, "gain_std": 0.1498267650604248 } }, "exp_gain_correct_during_flat_capture": true, "smooth_ksize": 31, "min_gain": 0.25, "max_gain": 4.0, "notes": "" } }