Commit 48c93f00 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: MB convert erase-first overload - undefined tiles reach consolidation as NaN

Per Andrey: undefined tiles (= not in the task list; the fixed-length 5120
arrays represent them as nulls) must be handled by the channel consolidation
- weighted-by-existing average, all-NaN tile when no sensor has it (now Java
CuasTD.consolidateSensorsTD, later the CUDA clt_average_sensors kernel).
The consolidation detects missing by NaN, but the MB double convert ran with
erase=-1, leaving STALE (valid-looking) data at undefined tiles.

- ImageDtt.interCorrTDMotionBlur: new erase-capable overload (erase_clt_first:
  >0 NaN, 0 zeros, <0 legacy no-erase) - erases before the FIRST (SET) convert
  only; the SECOND (negative-scale SUBTRACT) never erases. Legacy signature
  delegates with -1: oracle/SfM callers byte-identical.
- CuasRender MB path uses erase_clt_first=1: the GPU TD buffer's NaN pattern
  now mirrors the task-list membership, so consolidation + renders see
  undefined tiles as NaN - never the previous scene.

Verified: mvn -DskipTests clean package OK.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 72fd0677
......@@ -115,9 +115,9 @@ public class CuasRender {
if (mb_vectors != null) {
// Motion-blur compensation: TWO task sets (original positive scale + shifted
// negative scale), double convert_direct - the oracle machinery
// (setInterTasksMotionBlur / interCorrTDMotionBlur). NOTE: no erased re-convert
// here (it would destroy the two-pass accumulation) - tiles outside the task
// set keep the previous scene's data; comparisons must mask to task tiles.
// (setInterTasksMotionBlur / interCorrTDMotionBlur). The FIRST convert erases
// the CLT to NaN, so tiles absent from the task set reach the NaN-aware channel
// consolidation (and the renders) as NaN - never stale data (Andrey 07/05/2026).
final TpTask [][] tp_tasks2 = GpuQuad.setInterTasksMotionBlur(
scene.getNumSensors(),
img_width,
......@@ -138,6 +138,7 @@ public class CuasRender {
}
image_dtt.interCorrTDMotionBlur(
clt_parameters.img_dtt,
1, // erase_clt_first: NaN outside the task set // By Claude on 07/05/2026
tp_tasks2,
null,
clt_parameters.gpu_sigma_r,
......
......@@ -1287,6 +1287,41 @@ public class ImageDtt extends ImageDttCPU {
final int sensor_mask_inter, // The bitmask - which sensors to correlate, -1 - all.
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
interCorrTDMotionBlur( // erase-capable version, -1 = legacy no-erase // By Claude on 07/05/2026
imgdtt_params, -1, tp_tasks, fcorr_td,
gpu_sigma_r, gpu_sigma_b, gpu_sigma_g, gpu_sigma_m,
gpu_sigma_rb_corr, gpu_sigma_corr, gpu_sigma_log_corr,
corr_red, corr_blue, sensor_mask_inter, threadsMax, globalDebugLevel);
}
/**
* Same as interCorrTDMotionBlur() above with control of erasing the CLT before the
* FIRST (positive-scale, SET) convert: erase_clt_first >0 - fill NaN, 0 - fill 0.0,
* <0 - no erase (legacy). NaN-erase makes tiles absent from the task set read as NaN
* downstream (imclt renders; the NaN-aware channel consolidation
* CuasTD.consolidateSensorsTD - weighted-by-existing-tiles average, all-NaN where no
* sensor has the tile) instead of stale data from the previous conversion. The SECOND
* (negative-scale, SUBTRACT-accumulate) convert never erases.
* By Claude on 07/05/2026, from Andrey's requirement.
*/
public void interCorrTDMotionBlur(
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
final int erase_clt_first, // erase CLT before the FIRST convert: >0 NaN, 0 zeros, <0 keep // By Claude on 07/05/2026
final TpTask[][] tp_tasks,
final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
final double gpu_sigma_r, // 0.9, 1.1
final double gpu_sigma_b, // 0.9, 1.1
final double gpu_sigma_g, // 0.6, 0.7
final double gpu_sigma_m, // = 0.4; // 0.7;
final double gpu_sigma_rb_corr, // = 0.5; // apply LPF after accumulating R and B correlation before G, monochrome ? 1.0 :
final double gpu_sigma_corr, // = 0.9;gpu_sigma_corr_m
final double gpu_sigma_log_corr, // hpf to reduce dynamic range for correlations
final double corr_red, // +used
final double corr_blue,// +used
final int sensor_mask_inter, // The bitmask - which sensors to correlate, -1 - all.
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int numcol = isMonochrome()?1:3;
final double [] col_weights= new double [numcol]; // colors are RBG
......@@ -1346,7 +1381,7 @@ public class ImageDtt extends ImageDttCPU {
false); // boolean use_aux // while is it in class member? - just to be able to free
// Skipping if ((fdisp_dist != null) || (fpxpy != null)) {...
gpuQuad.execConvertDirect(false, null, -1); // Convert primary image, no erase (each tile will be SET as scales > 0
gpuQuad.execConvertDirect(false, null, erase_clt_first); // Convert primary image (erase per erase_clt_first; each task tile is SET as scales > 0) // By Claude on 07/05/2026
// set secondary tasks and perform direct conversion to TD, subtracting from the converted primary
gpuQuad.setTasks( // copy tp_tasks to the GPU memory
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment