@@ -306,6 +306,20 @@ Both then call the same `prepareMotionBasedSequence()` path and therefore use th
...
@@ -306,6 +306,20 @@ Both then call the same `prepareMotionBasedSequence()` path and therefore use th
Practical consequence: if targets are too fast and the peaks in `*-FAST-CORR2D.tiff` hit the `+-7` tile borders, reducing `cuas_corr_offset` will reduce the apparent motion in both FAST and SLOW modes. There is currently no separate fast-only correlation offset parameter; adding one would require a code change.
Practical consequence: if targets are too fast and the peaks in `*-FAST-CORR2D.tiff` hit the `+-7` tile borders, reducing `cuas_corr_offset` will reduce the apparent motion in both FAST and SLOW modes. There is currently no separate fast-only correlation offset parameter; adding one would require a code change.
Velocity units in the current implementation are intentionally split:
-`RSLT_VX` / `RSLT_VY` store the raw displacement measured by the correlation peak over one pair separation, i.e. over `cuas_corr_offset` scenes.
- To convert these stored values to pixels per frame, multiply by `1.0 / cuas_corr_offset`.
- To convert them to displacement between neighboring keyframe centers, multiply by `getCorrIncExact() / cuas_corr_offset`.
Odd `cuas_corr_offset` with `cuas_half_step=true` needs special care:
- the scan index increment is still integer (`getCorrInc()` truncates `cuas_corr_offset / 2`),
- but the intended keyframe-center geometry remains half the full offset (`getCorrIncExact()` uses `0.5 * cuas_corr_offset`),
- so midpoint / before-after chaining logic must use the exact geometric half-step, not the truncated scan increment.
This distinction is what caused the temporary `1.25` compensation when `cuas_corr_offset=5`: the scan step became `2`, but the intended half-step geometry was still `2.5`.
### Where the current code does this
### Where the current code does this
-`CuasRanging.processMovingTargetsMulti()` renders the per-sequence `...-CUAS...` stack and applies the unsharp mask before creating `fpixels`.
-`CuasRanging.processMovingTargetsMulti()` renders the per-sequence `...-CUAS...` stack and applies the unsharp mask before creating `fpixels`.
-`CuasMotion.processMovingTargetsMulti()` runs the fast/slow motion-target preparation and resolves non-conflicting motion candidates.
-`CuasMotion.processMovingTargetsMulti()` runs the fast/slow motion-target preparation and resolves non-conflicting motion candidates.
...
@@ -336,6 +350,81 @@ Generate and save detected targets
...
@@ -336,6 +350,81 @@ Generate and save detected targets
If that checkbox is off, the code will still do earlier target/ranging work but will skip the accumulated target TIFF/video generation stage.
If that checkbox is off, the code will still do earlier target/ranging work but will skip the accumulated target TIFF/video generation stage.
### Operational note: sequence continuity is required for CUAS target detection
There is now an explicit distinction between:
- the early per-sequence preparation stages (initial orientation, center/reference generation, FPN extraction), and
- the later target-detection stages that depend on temporal continuity.
The local switch:
```
clt_parameters.imp.cuas_targets_en
```
is used to disable target detection while still allowing the earlier orientation/FPN stages to run. This is useful when debugging sequence geometry, IMS consistency, or FPN extraction without generating target products.
For CUAS processing, a real camera movement or a sharp IMU orientation discontinuity inside one source-list sequence is considered invalid input, not a condition to be automatically "recovered". The later CUAS stages use running temporal references, including reuse of the previous `~8 s` sequence when building the reference image for target detection. If the camera moved in between, that reference image no longer matches the later data.
Operational rule:
- if the camera was moved, or the IMS quaternion has a discontinuity large enough to break overlap/continuity, split the sequence;
- do not reuse the previous running-average reference across that split;
- process the "good" part of the sequence separately from the later part;
- if needed, use `.list``first/last` trimming to isolate the valid sub-range;
- for the later sub-range, start a new sequence rather than continuing through the bad transition.
As of April 2026, the CUAS code is intentionally conservative here: if initial orientations fail in CUAS mode because IMS/orientation input is inconsistent, processing aborts with a log message instead of retrying the same bad tail indefinitely.
### Next calibration step: target-assisted LY for LV data
The next planned work after restoring/stabilizing CUAS detection is to improve LWIR field calibration ("Lazy Eye", `LY`) for the Latvia (`LV`) data.
Calibration is currently understood as two layers:
1. Factory calibration:
- uses the special `3.0 m x 7.0 m` curved checkerboard target,
- measures lens distortion / aberration, including non-radial terms,
- is assumed fixed for the current camera unless the optics themselves change.
- convergence/divergence (`disparity at infinity`),
- all remaining relative attitude corrections.
The existing `LY` implementation already supports multiscene adjustment. The planned new functionality is not a new solver; it is a new way to prepare the calibration data for that existing multiscene `LY` code.
Why this is needed for LV:
- the 2025 data often had textured clouds across much of the sky, so ordinary scene content was sufficient for `LY`,
- the Latvia data has mostly clear blue sky,
- usable static texture is concentrated near the bottom of the FOV,
- current calibration is good enough for target detection,
- but accurate ranging needs much better residual disparity accuracy.
Planned approach:
- first restore and validate moving-target detection/tracking,
- then use detected targets themselves as additional `LY` features,
- combine multiple scenes so the selected calibration data covers most of the FOV, especially the corners,
- reuse the simultaneity of each LWIR scene: each accepted target contributes measurements from all 16 sensors at the same timestamp.
One likely implementation path is to build a composite/synthetic calibration scene:
- instead of a few targets (`~5`) per timestamp, gather targets from many timestamps,
- keep each accepted target as a simultaneous 16-view measurement from one scene,
- merge many such measurements into a synthetic scene or multiscene bundle,
- effectively present the `LY` stage with a much denser set of valid points (`~500` targets instead of `~5`), while still respecting the per-scene simultaneity needed by the geometry.
Operational goal:
- use textured terrain where available,
- augment it with detected airborne targets (mostly birds in the current LV data, possibly drones later),
- solve `LY` on a selected subset of scenes that together span the full FOV,
- then reuse the improved `LY` correction for final disparity/ranging runs.
This work should stay separate from factory calibration logic. The intended change is in scene/feature preparation and selection, not in the underlying multiscene `LY` optimizer.
## Latest Additions
## Latest Additions
### Segment freezing with `keep_segments`
### Segment freezing with `keep_segments`
Index scenes (`*-index`) contain `*-INTERFRAME.corr-xml` with keys like:
Index scenes (`*-index`) contain `*-INTERFRAME.corr-xml` with keys like: