euler-preprocess 3.3.0__tar.gz → 3.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/PKG-INFO +20 -1
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/README.md +19 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/models.py +21 -18
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/transform.py +772 -48
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess.egg-info/PKG-INFO +20 -1
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/pyproject.toml +1 -1
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_fog_aux_outputs.py +253 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/__init__.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/cli.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/__init__.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/dataset.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/device.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/intrinsics.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/io.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/logging.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/noise.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/normalize.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/output.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/sampling.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/common/transform.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/__init__.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/airlight_from_sky.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/atmospheric_light.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/augmentations.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/capture.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/dcp_airlight.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/dcp_airlight_torch.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/dcp_heuristic_airlight.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/dcp_heuristic_airlight_torch.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/foggify.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/foggify_logging.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/inference.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/logging.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/fog/pipeline.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/radial/__init__.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/radial/transform.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/sky_depth/__init__.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess/sky_depth/transform.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess.egg-info/SOURCES.txt +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess.egg-info/dependency_links.txt +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess.egg-info/entry_points.txt +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess.egg-info/requires.txt +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/euler_preprocess.egg-info/top_level.txt +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/setup.cfg +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_airlight_fallback.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_cli_sample_selection.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_dcp_heuristic_airlight.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_foggify_integration.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_radial.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_sky_depth.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_source_backed_output.py +0 -0
- {euler_preprocess-3.3.0 → euler_preprocess-3.5.0}/tests/test_zip_output.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: euler-preprocess
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0
|
|
4
4
|
Summary: Physics-based preprocessing (fog, etc.) for RGB+depth datasets
|
|
5
5
|
Requires-Python: >=3.9
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -148,6 +148,7 @@ Controls the fog simulation.
|
|
|
148
148
|
"depth_scale": 1.0,
|
|
149
149
|
"resize_depth": true,
|
|
150
150
|
"contrast_threshold": 0.05,
|
|
151
|
+
"mode": "sample",
|
|
151
152
|
"device": "cpu",
|
|
152
153
|
"gpu_batch_size": 4,
|
|
153
154
|
"capture": { "preset": "camera" },
|
|
@@ -165,6 +166,7 @@ Controls the fog simulation.
|
|
|
165
166
|
| `depth_scale` | Multiplier applied to depth values after loading. |
|
|
166
167
|
| `resize_depth` | Resize the depth map to match the RGB resolution (bilinear). |
|
|
167
168
|
| `contrast_threshold` | Threshold *C_t* used in the visibility-to-attenuation conversion (default `0.05`). |
|
|
169
|
+
| `mode` | Optional scenario mode. Omit it or use `"sample"` for current one-scenario-per-image behavior; use `"progressive"` to render every scenario step for every image. |
|
|
168
170
|
| `device` | `"cpu"`, `"cuda"`, `"mps"`, or `"gpu"` (alias for cuda). |
|
|
169
171
|
| `gpu_batch_size` | Batch size when running on GPU. Uniform-model samples are batched; heterogeneous samples are processed individually. |
|
|
170
172
|
| `capture` / `capture_artifacts` | Optional post-fog camera artifact pipeline. Omit it or set `{"stages": []}` for the legacy no-op path. Set `true`, `{"preset": "camera"}`, or a custom `stages` list to enable optics, raw sensor, ISP, and compression artifacts. |
|
|
@@ -404,6 +406,19 @@ compression together:
|
|
|
404
406
|
`condition_profiles`; if omitted, the stage continues sampling its own profile
|
|
405
407
|
weights locally.
|
|
406
408
|
|
|
409
|
+
Set top-level `"mode": "progressive"` to emit every configured scenario for
|
|
410
|
+
every input image instead of sampling one scenario. Each scenario accepts
|
|
411
|
+
`"steps"` and `"progressive_weight"` (or `"max_weight"` / `"weight"` as
|
|
412
|
+
aliases); the transform writes steps from weight `0` through the scenario's
|
|
413
|
+
configured weight, and weight `1` matches the original scenario. Fog density is
|
|
414
|
+
progressed in scattering-coefficient space, while numeric camera/config values
|
|
415
|
+
blend from the base config toward the scenario config. Progressive blends clamp
|
|
416
|
+
probability-like values and non-negative physical factors back into valid
|
|
417
|
+
mathematical domains so extrapolated weights above `1` do not create invalid
|
|
418
|
+
render parameters.
|
|
419
|
+
Source-backed outputs are written as `fog_progression` variants under each
|
|
420
|
+
source file id.
|
|
421
|
+
|
|
407
422
|
### Fog Model
|
|
408
423
|
|
|
409
424
|
The core equation is the **Koschmieder model** (atmospheric scattering):
|
|
@@ -482,6 +497,10 @@ Each fog model can override the dampening curve:
|
|
|
482
497
|
|
|
483
498
|
The factor is:
|
|
484
499
|
`min_factor + (max_factor - min_factor) / (1 + strength * beta / reference_beta)`.
|
|
500
|
+
`min_factor` and `max_factor` must be finite and non-negative. Values above
|
|
501
|
+
`1.0` are allowed when you intentionally want to brighten estimated airlight;
|
|
502
|
+
the final RGB output is still clamped to the valid image range. `strength`
|
|
503
|
+
must remain finite and non-negative.
|
|
485
504
|
`reference_beta` is either `reference_scattering_coefficient` /
|
|
486
505
|
`reference_beta`, or it is derived from `reference_visibility_m` using the
|
|
487
506
|
model's contrast threshold. The default applies only when `atmospheric_light`
|
|
@@ -134,6 +134,7 @@ Controls the fog simulation.
|
|
|
134
134
|
"depth_scale": 1.0,
|
|
135
135
|
"resize_depth": true,
|
|
136
136
|
"contrast_threshold": 0.05,
|
|
137
|
+
"mode": "sample",
|
|
137
138
|
"device": "cpu",
|
|
138
139
|
"gpu_batch_size": 4,
|
|
139
140
|
"capture": { "preset": "camera" },
|
|
@@ -151,6 +152,7 @@ Controls the fog simulation.
|
|
|
151
152
|
| `depth_scale` | Multiplier applied to depth values after loading. |
|
|
152
153
|
| `resize_depth` | Resize the depth map to match the RGB resolution (bilinear). |
|
|
153
154
|
| `contrast_threshold` | Threshold *C_t* used in the visibility-to-attenuation conversion (default `0.05`). |
|
|
155
|
+
| `mode` | Optional scenario mode. Omit it or use `"sample"` for current one-scenario-per-image behavior; use `"progressive"` to render every scenario step for every image. |
|
|
154
156
|
| `device` | `"cpu"`, `"cuda"`, `"mps"`, or `"gpu"` (alias for cuda). |
|
|
155
157
|
| `gpu_batch_size` | Batch size when running on GPU. Uniform-model samples are batched; heterogeneous samples are processed individually. |
|
|
156
158
|
| `capture` / `capture_artifacts` | Optional post-fog camera artifact pipeline. Omit it or set `{"stages": []}` for the legacy no-op path. Set `true`, `{"preset": "camera"}`, or a custom `stages` list to enable optics, raw sensor, ISP, and compression artifacts. |
|
|
@@ -390,6 +392,19 @@ compression together:
|
|
|
390
392
|
`condition_profiles`; if omitted, the stage continues sampling its own profile
|
|
391
393
|
weights locally.
|
|
392
394
|
|
|
395
|
+
Set top-level `"mode": "progressive"` to emit every configured scenario for
|
|
396
|
+
every input image instead of sampling one scenario. Each scenario accepts
|
|
397
|
+
`"steps"` and `"progressive_weight"` (or `"max_weight"` / `"weight"` as
|
|
398
|
+
aliases); the transform writes steps from weight `0` through the scenario's
|
|
399
|
+
configured weight, and weight `1` matches the original scenario. Fog density is
|
|
400
|
+
progressed in scattering-coefficient space, while numeric camera/config values
|
|
401
|
+
blend from the base config toward the scenario config. Progressive blends clamp
|
|
402
|
+
probability-like values and non-negative physical factors back into valid
|
|
403
|
+
mathematical domains so extrapolated weights above `1` do not create invalid
|
|
404
|
+
render parameters.
|
|
405
|
+
Source-backed outputs are written as `fog_progression` variants under each
|
|
406
|
+
source file id.
|
|
407
|
+
|
|
393
408
|
### Fog Model
|
|
394
409
|
|
|
395
410
|
The core equation is the **Koschmieder model** (atmospheric scattering):
|
|
@@ -468,6 +483,10 @@ Each fog model can override the dampening curve:
|
|
|
468
483
|
|
|
469
484
|
The factor is:
|
|
470
485
|
`min_factor + (max_factor - min_factor) / (1 + strength * beta / reference_beta)`.
|
|
486
|
+
`min_factor` and `max_factor` must be finite and non-negative. Values above
|
|
487
|
+
`1.0` are allowed when you intentionally want to brighten estimated airlight;
|
|
488
|
+
the final RGB output is still clamped to the valid image range. `strength`
|
|
489
|
+
must remain finite and non-negative.
|
|
471
490
|
`reference_beta` is either `reference_scattering_coefficient` /
|
|
472
491
|
`reference_beta`, or it is derived from `reference_visibility_m` using the
|
|
473
492
|
model's contrast threshold. The default applies only when `atmospheric_light`
|
|
@@ -100,8 +100,12 @@ DEFAULT_MODEL_CONFIGS = {
|
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
def visibility_to_k(visibility_m: float, contrast_threshold: float) -> float:
|
|
103
|
-
if visibility_m <= 0:
|
|
103
|
+
if not math.isfinite(visibility_m) or visibility_m <= 0:
|
|
104
104
|
raise ValueError(f"Visibility must be > 0, got {visibility_m}")
|
|
105
|
+
if not math.isfinite(contrast_threshold) or not 0.0 < contrast_threshold < 1.0:
|
|
106
|
+
raise ValueError(
|
|
107
|
+
f"Contrast threshold must be in (0, 1), got {contrast_threshold}"
|
|
108
|
+
)
|
|
105
109
|
return -math.log(contrast_threshold) / visibility_m
|
|
106
110
|
|
|
107
111
|
|
|
@@ -132,7 +136,7 @@ def resolve_scattering_coefficient(
|
|
|
132
136
|
beta_spec = model_cfg.get("scattering_coefficient", model_cfg.get("beta"))
|
|
133
137
|
if beta_spec is not None:
|
|
134
138
|
beta = float(sample_value(beta_spec, rng))
|
|
135
|
-
if beta < 0:
|
|
139
|
+
if not math.isfinite(beta) or beta < 0:
|
|
136
140
|
raise ValueError(f"Scattering coefficient must be >= 0, got {beta}")
|
|
137
141
|
return beta, None, contrast_threshold
|
|
138
142
|
|
|
@@ -222,13 +226,13 @@ def resolve_airlight_dampening_config(
|
|
|
222
226
|
rng,
|
|
223
227
|
"airlight_dampening.strength",
|
|
224
228
|
)
|
|
225
|
-
if
|
|
229
|
+
if min_factor < 0.0:
|
|
226
230
|
raise ValueError(
|
|
227
|
-
f"airlight_dampening.min_factor must be
|
|
231
|
+
f"airlight_dampening.min_factor must be >= 0, got {min_factor}"
|
|
228
232
|
)
|
|
229
|
-
if
|
|
233
|
+
if max_factor < 0.0:
|
|
230
234
|
raise ValueError(
|
|
231
|
-
f"airlight_dampening.max_factor must be
|
|
235
|
+
f"airlight_dampening.max_factor must be >= 0, got {max_factor}"
|
|
232
236
|
)
|
|
233
237
|
if min_factor > max_factor:
|
|
234
238
|
raise ValueError("airlight_dampening.min_factor must be <= max_factor")
|
|
@@ -504,9 +508,12 @@ def _scale_pixels(value, rng: np.random.Generator, name: str) -> int:
|
|
|
504
508
|
def _sample_float(value, rng: np.random.Generator, name: str) -> float:
|
|
505
509
|
sampled = sample_value(value, rng)
|
|
506
510
|
try:
|
|
507
|
-
|
|
511
|
+
resolved = float(sampled)
|
|
508
512
|
except (TypeError, ValueError) as exc:
|
|
509
513
|
raise ValueError(f"{name} must resolve to a number, got {sampled!r}") from exc
|
|
514
|
+
if not math.isfinite(resolved):
|
|
515
|
+
raise ValueError(f"{name} must be finite, got {resolved}")
|
|
516
|
+
return resolved
|
|
510
517
|
|
|
511
518
|
|
|
512
519
|
def _unique_positive_scales(scales: list[int]) -> list[int]:
|
|
@@ -801,9 +808,11 @@ def _gradient_enabled(
|
|
|
801
808
|
rng,
|
|
802
809
|
f"{name}.probability",
|
|
803
810
|
)
|
|
804
|
-
if
|
|
805
|
-
|
|
806
|
-
|
|
811
|
+
if probability <= 0.0:
|
|
812
|
+
return False
|
|
813
|
+
if probability >= 1.0:
|
|
814
|
+
return True
|
|
815
|
+
return bool(rng.random() < probability)
|
|
807
816
|
|
|
808
817
|
|
|
809
818
|
def _ls_gradient_factors_np(
|
|
@@ -885,10 +894,7 @@ def _weight_ls_gradient_by_opacity_np(
|
|
|
885
894
|
rng,
|
|
886
895
|
"ls_gradient.fog_opacity_weight",
|
|
887
896
|
)
|
|
888
|
-
|
|
889
|
-
raise ValueError(
|
|
890
|
-
f"ls_gradient.fog_opacity_weight must be in [0, 1], got {weight}"
|
|
891
|
-
)
|
|
897
|
+
weight = float(np.clip(weight, 0.0, 1.0))
|
|
892
898
|
if weight <= 0.0:
|
|
893
899
|
return factors
|
|
894
900
|
gamma = _sample_float(
|
|
@@ -917,10 +923,7 @@ def _weight_ls_gradient_by_opacity_torch(
|
|
|
917
923
|
rng,
|
|
918
924
|
"ls_gradient.fog_opacity_weight",
|
|
919
925
|
)
|
|
920
|
-
|
|
921
|
-
raise ValueError(
|
|
922
|
-
f"ls_gradient.fog_opacity_weight must be in [0, 1], got {weight}"
|
|
923
|
-
)
|
|
926
|
+
weight = float(np.clip(weight, 0.0, 1.0))
|
|
924
927
|
if weight <= 0.0:
|
|
925
928
|
return factors
|
|
926
929
|
gamma = _sample_float(
|