Commit 024b3bda authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: RT zero-DC conditioning + decoupled fat zero + borrowed-center DC appropriation

Three coupled improvements from tonight's design discussion with Andrey:

1. ZERO-DC in CuasConditioning (Config default ON): LWIR microbolometers are
   ADDITIVE (fixed tau=8ms exposure, F#~1 for NETD, ~100 counts/K) - day/night
   and seasons SHIFT the level, never scale it; the MCLT has no clean DC/AC
   separation, so a large DC (current ~-3500 counts under ~300 counts AC)
   spreads over many TD points and costs float32 mantissa bits. Subtract ONE
   common constant from all 16 sensors (pure shift, never rescale). AUTO level
   = MEDIAN OF THE TOP (SKY) HALF, robust to the snowy-ground-vs-summer-
   calibration mismatch and to targets.

2. RT-DECOUPLED FAT ZERO (curt.fz_inter=10000, curt.fz_intra=2000 reserved):
   the lean code erroneously used the INTRA getGpuFatZero (2000) instead of
   the INTER value - Andrey's FZ sweep (200/1000/3000/10000: corrRMS
   .54/.39/.37/.31, roll bias +.80/+.62/+.50/+.39) independently rediscovered
   the oracle's INTER operating point (10000). RT now owns its FZ pair, no
   AUX switch; legacy gpu_fatz*/FOPEN configs untouched. Sweep recorded as
   characterization: FZ tolerant over a broad range; revisit only together
   with the argmax method redesign (sharp peaks starve the centroid).

3. BORROWED-CENTER APPROPRIATION (curt.dc_center, 0=auto): the restored
   CenterClt reflects its own footage vintage - offset it ONCE at the borrow
   boundary (firewall: never re-compensate downstream) to match the zero-sky
   scenes. Auto level = sky-half median of the borrowed center average,
   ADOPTED into curt.dc_center (persisted with the config - borrowable later
   like the photometric calibration). Mechanics: DC pattern = CLT of a
   uniform image via the existing back-propagation convert (setImageCenter +
   no_kernels + use_center_image, the CorrectionFPN recipe); failure-safe
   (any missing piece leaves the reference unchanged, with a warning).

Roadmap recorded: per-pixel offset (recalibrated per-sensor + FPN) and
per-pixel scale maps to the GPU; the average stored in TD AFTER LoG
(aberration+LoG combined kernels) for fpixels subtraction - possibly for
poses too; center-average window length trades reference stability vs
extremely-slow-target detectability.

Verified: mvn -DskipTests clean package OK.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 0a8d2415
...@@ -57,6 +57,16 @@ public class CuasConditioning { ...@@ -57,6 +57,16 @@ public class CuasConditioning {
public double rowcol_weight_outlier= 0.01; // small weight for out-of-range pixels public double rowcol_weight_outlier= 0.01; // small weight for out-of-range pixels
public boolean photometric = true; // apply scale*(raw-offset) [+ scales2 quadratic] public boolean photometric = true; // apply scale*(raw-offset) [+ scales2 quadratic]
public boolean apply_fpn = true; // subtract per-pixel FPN (the offset map's per-pixel part) public boolean apply_fpn = true; // subtract per-pixel FPN (the offset map's per-pixel part)
// Zero-DC (Andrey 2026-07-05, restoring a lost pre-CUAS invariant): the MCLT has no
// clean DC/AC separation - a DC constant spreads over many TD points, costing float32
// mantissa bits under the small AC signal (LWIR: ~100 counts/K, typical scene AC
// ~300 counts = ~3K, current DC ~ -3500). Subtract ONE constant from ALL sensors
// (pure shift - never rescale, counts stay physically meaningful; a common constant
// preserves the photometric equalization). dc_level = the constant to subtract;
// NaN = AUTO (the global mean over all sensors of this scene). A calibration-
// maintained fixed level (no scene-to-scene DC flicker) is the production target.
public boolean zero_dc = true; // By Claude on 07/05/2026
public double dc_level = Double.NaN; // NaN = auto (per-scene global mean) // By Claude on 07/05/2026
public Config() {} public Config() {}
} }
...@@ -101,6 +111,34 @@ public class CuasConditioning { ...@@ -101,6 +111,34 @@ public class CuasConditioning {
} }
} }
} }
// Zero-DC: one common constant subtracted from ALL sensors (see Config docs).
// AUTO level = MEDIAN OF THE TOP HALF of the frame (y < height/2), pooled over all
// sensors: for CUAS the sky background is what matters, and the median is robust to
// both the (snowy March Latvia vs summer-calibration) ground and to targets. The
// same level must be subtracted from the BORROWED averaged center image at borrow
// time (firewall: borrowed data zeroed once at the boundary, never re-compensated).
// By Claude on 07/05/2026, from Andrey's design.
if (cfg.zero_dc) {
double level = cfg.dc_level;
if (Double.isNaN(level)) { // auto: median of the top (sky) half, all sensors pooled
final int height = ((image_data[0] != null) && (image_data[0][0] != null)) ?
image_data[0][0].length / width : 0;
final int top_pix = (height / 2) * width;
double [] samples = new double [num_sens * top_pix];
int n = 0;
for (int s = 0; s < num_sens; s++) if (image_data[s] != null && image_data[s][0] != null) {
final double [] px = image_data[s][0];
for (int i = 0; i < top_pix; i++) if (!Double.isNaN(px[i])) samples[n++] = px[i];
}
if (n == 0) return;
java.util.Arrays.sort(samples, 0, n);
level = samples[n/2];
}
for (int s = 0; s < num_sens; s++) if (image_data[s] != null && image_data[s][0] != null) {
final double [] px = image_data[s][0];
for (int i = 0; i < px.length; i++) px[i] -= level;
}
}
} }
/** /**
......
...@@ -398,7 +398,7 @@ public class CuasPoseRT { ...@@ -398,7 +398,7 @@ public class CuasPoseRT {
gpuQuad, gpuQuad,
td_tiles, td_tiles,
0xFE, // corr_type (sum slot, as CuasMotion) 0xFE, // corr_type (sum slot, as CuasMotion)
clt_parameters.getGpuFatZero(scene.isMonochrome()), clt_parameters.curt.fz_inter, // RT-decoupled INTER fat zero (was erroneously the INTRA getGpuFatZero) // By Claude on 07/05/2026
debugLevel); debugLevel);
if (corr_pd == null) { if (corr_pd == null) {
System.out.println("leanMeasure(): convertTDtoPD returned null for scene "+scene.getImageName()); System.out.println("leanMeasure(): convertTDtoPD returned null for scene "+scene.getImageName());
...@@ -442,6 +442,111 @@ public class CuasPoseRT { ...@@ -442,6 +442,111 @@ public class CuasPoseRT {
return com.elphel.imagej.gpu.GPUTileProcessor.DTT_SIZE; return com.elphel.imagej.gpu.GPUTileProcessor.DTT_SIZE;
} }
/**
* Appropriate the borrowed center reference: subtract the DC level from the
* reference CLT already uploaded to the GPU, so it matches the zero-sky conditioned
* scenes (the MCLT has no clean DC/AC separation - a DC constant spreads over many
* TD points and costs float32 mantissa bits; LWIR is ADDITIVE: day/night and seasons
* shift the level, they do not scale it - the borrowed center reflects its own
* footage vintage).
* Level: curt.dc_center; 0 = AUTO - median of the top (sky) half of the borrowed
* center average image, then ADOPTED into curt.dc_center (persisted on the next
* configuration save - borrowable later, like the photometric calibration).
* Mechanics: the CLT of a UNIFORM image (the DC pattern - identical for every
* converted tile) is obtained through the existing back-propagation convert
* (setImageCenter + no_kernels + use_center_image, the CorrectionFPN recipe), then
* fclt_zeroed = fclt - level*pattern is re-uploaded to all reference slots. Only the
* task tiles get the pattern (erase=NaN elsewhere) - sufficient: the correlation
* reads task tiles only. Failure-safe: any missing piece leaves the reference as-is.
* By Claude on 07/05/2026, from Andrey's design.
*/
public static void appropriateCenterDC(
final CLTParameters clt_parameters,
final QuadCLT center_CLT,
final TpTask [] tp_tasks_center,
final float [] fclt0,
final int debugLevel) {
final GpuQuad gpuQuad = center_CLT.getGPUQuad();
double level = clt_parameters.curt.dc_center;
if (level == 0.0) { // auto: median of the top (sky) half of the borrowed center average
final ImagePlus imp_avg = center_CLT.getCenterAverage();
if (imp_avg == null) {
System.out.println("appropriateCenterDC(): no center average image - reference NOT offset");
return;
}
final float [] apx = (float []) imp_avg.getProcessor().getPixels();
final int width = imp_avg.getWidth();
final int top_pix = (imp_avg.getHeight() / 2) * width;
final float [] samples = new float [top_pix];
int n = 0;
for (int i = 0; i < top_pix; i++) if (!Float.isNaN(apx[i])) samples[n++] = apx[i];
if (n == 0) {
System.out.println("appropriateCenterDC(): center average all-NaN in the sky half - reference NOT offset");
return;
}
Arrays.sort(samples, 0, n);
level = samples[n/2];
clt_parameters.curt.dc_center = level; // adopt: persisted on the next config save
System.out.println("appropriateCenterDC(): AUTO center DC level = "+level+
" (median of the sky half of the borrowed center average), adopted into curt.dc_center");
}
// the DC pattern: CLT of a uniform image through the back-propagation convert
final int [] wh = center_CLT.getGeometryCorrection().getSensorWH();
final double [][] saved_center = center_CLT.getImageCenter();
float [] pattern = null;
try {
final double [][] uniform = new double [][] {new double [wh[0]*wh[1]]};
Arrays.fill(uniform[0], 1.0);
center_CLT.setImageCenter(uniform);
final ImageDtt image_dtt = new ImageDtt(
center_CLT.getNumSensors(),
clt_parameters.transform_size,
clt_parameters.img_dtt,
center_CLT.isAux(),
center_CLT.isMonochrome(),
center_CLT.isLwir(),
clt_parameters.getScaleStrength(center_CLT.isAux()),
center_CLT.getGPU());
image_dtt.preSetReferenceTD( // tasks + offsets, no convert
clt_parameters.img_dtt,
tp_tasks_center,
true, // keep_tiles_offsets
clt_parameters.gpu_sigma_r,
clt_parameters.gpu_sigma_b,
clt_parameters.gpu_sigma_g,
clt_parameters.gpu_sigma_m,
debugLevel);
image_dtt.execConvertDirect(
false, // use_reference_buffer: SCENE buffer (scratch)
null, // wh
1, // erase_clt: NaN outside tasks
true, // no_kernels
true); // use_center_image (uniform)
pattern = gpuQuad.getCltData(false)[0];
} catch (Exception e) {
System.out.println("appropriateCenterDC(): DC-pattern conversion FAILED ("+e.getMessage()+
") - reference NOT offset");
pattern = null;
} finally {
center_CLT.setImageCenter(saved_center); // never leave back-propagate mode on
}
if (pattern == null) return;
final float [] fclt_zeroed = fclt0.clone();
int n_off = 0;
for (int i = 0; i < fclt_zeroed.length; i++) {
final float p = pattern[i];
if (!Float.isNaN(p) && !Float.isNaN(fclt_zeroed[i])) {
fclt_zeroed[i] -= (float) (level * p);
n_off++;
}
}
for (int ncam = 0; ncam < center_CLT.getNumSensors(); ncam++) {
gpuQuad.setCltData(ncam, fclt_zeroed, true); // reference buffer, all slots (merge_channels convention)
}
System.out.println("appropriateCenterDC(): reference CLT offset by "+level+
" over "+n_off+" TD points (task tiles)");
}
/** /**
* Phase B lean per-scene fit: the measure<->solve cycle with leanMeasure() as the * Phase B lean per-scene fit: the measure<->solve cycle with leanMeasure() as the
* measurement engine and the same IntersceneLma solver/exit rules as the oracle * measurement engine and the same IntersceneLma solver/exit rules as the oracle
...@@ -667,6 +772,13 @@ public class CuasPoseRT { ...@@ -667,6 +772,13 @@ public class CuasPoseRT {
mb_max_gain, // double mb_max_gain, mb_max_gain, // double mb_max_gain,
null, // double [][] mb_vectors (center does not move) null, // double [][] mb_vectors (center does not move)
debugLevel); // int debug_level debugLevel); // int debug_level
// APPROPRIATE the borrowed center: offset the reference CLT so it matches the
// zero-sky conditioned scenes (curt.dc_center; 0 = auto from the borrowed center
// average, adopted for persistence). Firewall: the borrowed data is zeroed ONCE
// here at the boundary - nothing downstream compensates again. Failure-safe: any
// missing piece leaves the reference unchanged (a warning, not a break).
// By Claude on 07/05/2026, from Andrey's design.
appropriateCenterDC(clt_parameters, center_CLT, tp_tasks_center[0], fclt[0], debugLevel);
// ---- Stored poses (comparison truth + seed) ---- // ---- Stored poses (comparison truth + seed) ----
final ErsCorrection ers_center = center_CLT.getErsCorrection(); final ErsCorrection ers_center = center_CLT.getErsCorrection();
......
...@@ -29,6 +29,9 @@ public class CuasRtParameters { ...@@ -29,6 +29,9 @@ public class CuasRtParameters {
public boolean pose_img_save = false; // DEBUG: save the composite scenes actually correlated - imclt render of the consolidated 16-sensor TD average at the converged pose (-POSE-RT-COMPOSITE: z=scenes; NaN outside task tiles) + the virtual-center reference render (-POSE-RT-CENTER-REF). Lean engine only. // By Claude on 07/04/2026 public boolean pose_img_save = false; // DEBUG: save the composite scenes actually correlated - imclt render of the consolidated 16-sensor TD average at the converged pose (-POSE-RT-COMPOSITE: z=scenes; NaN outside task tiles) + the virtual-center reference render (-POSE-RT-CENTER-REF). Lean engine only. // By Claude on 07/04/2026
public boolean pose_stored = false; // DEBUG: decouple rendering/measurement from the LMA - use the STORED (oracle vintage) pose for every scene, no adjustment; one leanMeasure per scene feeds -POSE-RT-HYPER/-CORR2D/-COMPOSITE. The composite must then match the oracle CUAS-MERGED-CUAS-DBG renders tile-for-tile. Lean engine only. // By Claude on 07/04/2026 public boolean pose_stored = false; // DEBUG: decouple rendering/measurement from the LMA - use the STORED (oracle vintage) pose for every scene, no adjustment; one leanMeasure per scene feeds -POSE-RT-HYPER/-CORR2D/-COMPOSITE. The composite must then match the oracle CUAS-MERGED-CUAS-DBG renders tile-for-tile. Lean engine only. // By Claude on 07/04/2026
public boolean rend_test = false; // MINIMAL RT ingest+render test (CuasRender.testRenderSequence, takes precedence over pose test): per scene raw /jp4/ -> conditionSceneToGpu -> virtual-grid render at BORROWED stored pose+ERS rates -> -CUAS-RT-RENDER hyperstack [s00..s15, merged][scenes], comparable to -CUAS-INDIVIDUAL/MERGED-CUAS-DBG. Certify THIS before the pose test. // By Claude on 07/05/2026 public boolean rend_test = false; // MINIMAL RT ingest+render test (CuasRender.testRenderSequence, takes precedence over pose test): per scene raw /jp4/ -> conditionSceneToGpu -> virtual-grid render at BORROWED stored pose+ERS rates -> -CUAS-RT-RENDER hyperstack [s00..s15, merged][scenes], comparable to -CUAS-INDIVIDUAL/MERGED-CUAS-DBG. Certify THIS before the pose test. // By Claude on 07/05/2026
public double fz_inter = 10000.0; // RT fat zero, INTER (pose/motion: scene x virtual-center correlation). DECOUPLED from the legacy gpu_fatz*/AUX switches (which stay untouched for non-RT/FOPEN). Value is for a single physical-pair amplitude; FZ ~ amplitude^2 in the GPU normalize - scale down x4..x16 for consolidated-average applications as needed. 10000 = the proven oracle INTER operating point (the lean code erroneously used the INTRA value before). // By Claude on 07/05/2026
public double fz_intra = 2000.0; // RT fat zero, INTRA (ranging/disparity: sensor-pair correlations within one scene). Reserved for the RT ranging path; same decoupling/scaling notes as fz_inter. // By Claude on 07/05/2026
public double dc_center = 0.0; // DC level of the BORROWED center (CLT-RESTORED/average): subtracted from the reference CLT at appropriation so it matches the zero-sky conditioned scenes (MCLT has no clean DC/AC split - a DC constant costs float32 accuracy). 0 = AUTO: compute as the median of the top (sky) half of the borrowed center average, adopt the value here (persisted on config save - borrowable later without our data, like the photometric calibration). Slow targets do not influence this shift. // By Claude on 07/05/2026
public double psf_radius = 1.0; // sensor PSF radius for LoG pre-filter public double psf_radius = 1.0; // sensor PSF radius for LoG pre-filter
public double n_sigma = 4.0; // cutoff LoG kernel array, number of sigmas public double n_sigma = 4.0; // cutoff LoG kernel array, number of sigmas
public int pyramid = 7; // temporal pyramid levels public int pyramid = 7; // temporal pyramid levels
...@@ -112,6 +115,12 @@ public class CuasRtParameters { ...@@ -112,6 +115,12 @@ public class CuasRtParameters {
"DEBUG: measure/render every scene at its STORED pose, skip the LMA entirely - decouples the task/render/correlation chain from the solver. Lean engine only."); "DEBUG: measure/render every scene at its STORED pose, skip the LMA entirely - decouples the task/render/correlation chain from the solver. Lean engine only.");
gd.addCheckbox ("CUAS RT render test (ingest+render)", this.rend_test, // By Claude on 07/05/2026 gd.addCheckbox ("CUAS RT render test (ingest+render)", this.rend_test, // By Claude on 07/05/2026
"MINIMAL standalone test (precedence over pose test): raw jp4 -> conditioning -> virtual-grid render at borrowed stored poses/ERS; saves -CUAS-RT-RENDER [s00..s15+merged][scenes] to compare against the -CUAS-*-DBG oracle products."); "MINIMAL standalone test (precedence over pose test): raw jp4 -> conditioning -> virtual-grid render at borrowed stored poses/ERS; saves -CUAS-RT-RENDER [s00..s15+merged][scenes] to compare against the -CUAS-*-DBG oracle products.");
gd.addNumericField("RT fat zero INTER (pose/motion)", this.fz_inter, 1,9,"", // By Claude on 07/05/2026
"RT-decoupled fat zero for INTERscene (pose/motion) correlations - the legacy gpu_fatz*/AUX parameters are not used by RT. For a single physical-pair amplitude; FZ ~ amplitude^2.");
gd.addNumericField("RT fat zero INTRA (ranging)", this.fz_intra, 1,9,"", // By Claude on 07/05/2026
"RT-decoupled fat zero for INTRAscene (ranging/disparity) correlations (reserved).");
gd.addNumericField("Center DC level (0 - auto)", this.dc_center, 3,9,"counts", // By Claude on 07/05/2026
"DC level subtracted from the borrowed center reference at appropriation (match the zero-sky scenes). 0 = compute from the center average (median of the sky half) and adopt; persisted with the configuration.");
gd.addMessage("=== LoG prefilter ==="); gd.addMessage("=== LoG prefilter ===");
gd.addNumericField("Optical PSF radius", this.psf_radius, 6,8,"pix", gd.addNumericField("Optical PSF radius", this.psf_radius, 6,8,"pix",
...@@ -248,6 +257,9 @@ public class CuasRtParameters { ...@@ -248,6 +257,9 @@ public class CuasRtParameters {
this.pose_img_save = gd.getNextBoolean(); // By Claude on 07/04/2026 this.pose_img_save = gd.getNextBoolean(); // By Claude on 07/04/2026
this.pose_stored = gd.getNextBoolean(); // By Claude on 07/04/2026 this.pose_stored = gd.getNextBoolean(); // By Claude on 07/04/2026
this.rend_test = gd.getNextBoolean(); // By Claude on 07/05/2026 this.rend_test = gd.getNextBoolean(); // By Claude on 07/05/2026
this.fz_inter = gd.getNextNumber(); // By Claude on 07/05/2026
this.fz_intra = gd.getNextNumber(); // By Claude on 07/05/2026
this.dc_center = gd.getNextNumber(); // By Claude on 07/05/2026
this.psf_radius = gd.getNextNumber(); this.psf_radius = gd.getNextNumber();
this.n_sigma = gd.getNextNumber(); this.n_sigma = gd.getNextNumber();
...@@ -328,6 +340,9 @@ public class CuasRtParameters { ...@@ -328,6 +340,9 @@ public class CuasRtParameters {
properties.setProperty(prefix+"pose_img_save", this.pose_img_save+""); // boolean // By Claude on 07/04/2026 properties.setProperty(prefix+"pose_img_save", this.pose_img_save+""); // boolean // By Claude on 07/04/2026
properties.setProperty(prefix+"pose_stored", this.pose_stored+""); // boolean // By Claude on 07/04/2026 properties.setProperty(prefix+"pose_stored", this.pose_stored+""); // boolean // By Claude on 07/04/2026
properties.setProperty(prefix+"rend_test", this.rend_test+""); // boolean // By Claude on 07/05/2026 properties.setProperty(prefix+"rend_test", this.rend_test+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"fz_inter", this.fz_inter+""); // double // By Claude on 07/05/2026
properties.setProperty(prefix+"fz_intra", this.fz_intra+""); // double // By Claude on 07/05/2026
properties.setProperty(prefix+"dc_center", this.dc_center+""); // double // By Claude on 07/05/2026
properties.setProperty(prefix+"psf_radius", this.psf_radius+""); // double properties.setProperty(prefix+"psf_radius", this.psf_radius+""); // double
properties.setProperty(prefix+"n_sigma", this.n_sigma+""); // double properties.setProperty(prefix+"n_sigma", this.n_sigma+""); // double
...@@ -408,6 +423,9 @@ public class CuasRtParameters { ...@@ -408,6 +423,9 @@ public class CuasRtParameters {
if (properties.getProperty(prefix+"pose_img_save")!=null) this.pose_img_save=Boolean.parseBoolean(properties.getProperty(prefix+"pose_img_save")); // By Claude on 07/04/2026 if (properties.getProperty(prefix+"pose_img_save")!=null) this.pose_img_save=Boolean.parseBoolean(properties.getProperty(prefix+"pose_img_save")); // By Claude on 07/04/2026
if (properties.getProperty(prefix+"pose_stored")!=null) this.pose_stored=Boolean.parseBoolean(properties.getProperty(prefix+"pose_stored")); // By Claude on 07/04/2026 if (properties.getProperty(prefix+"pose_stored")!=null) this.pose_stored=Boolean.parseBoolean(properties.getProperty(prefix+"pose_stored")); // By Claude on 07/04/2026
if (properties.getProperty(prefix+"rend_test")!=null) this.rend_test=Boolean.parseBoolean(properties.getProperty(prefix+"rend_test")); // By Claude on 07/05/2026 if (properties.getProperty(prefix+"rend_test")!=null) this.rend_test=Boolean.parseBoolean(properties.getProperty(prefix+"rend_test")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"fz_inter")!=null) this.fz_inter=Double.parseDouble(properties.getProperty(prefix+"fz_inter")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"fz_intra")!=null) this.fz_intra=Double.parseDouble(properties.getProperty(prefix+"fz_intra")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"dc_center")!=null) this.dc_center=Double.parseDouble(properties.getProperty(prefix+"dc_center")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"psf_radius")!=null) this.psf_radius=Double.parseDouble(properties.getProperty(prefix+"psf_radius")); if (properties.getProperty(prefix+"psf_radius")!=null) this.psf_radius=Double.parseDouble(properties.getProperty(prefix+"psf_radius"));
if (properties.getProperty(prefix+"n_sigma")!=null) this.n_sigma=Double.parseDouble(properties.getProperty(prefix+"n_sigma")); if (properties.getProperty(prefix+"n_sigma")!=null) this.n_sigma=Double.parseDouble(properties.getProperty(prefix+"n_sigma"));
...@@ -491,6 +509,9 @@ public class CuasRtParameters { ...@@ -491,6 +509,9 @@ public class CuasRtParameters {
cp.pose_img_save = this.pose_img_save; // By Claude on 07/04/2026 cp.pose_img_save = this.pose_img_save; // By Claude on 07/04/2026
cp.pose_stored = this.pose_stored; // By Claude on 07/04/2026 cp.pose_stored = this.pose_stored; // By Claude on 07/04/2026
cp.rend_test = this.rend_test; // By Claude on 07/05/2026 cp.rend_test = this.rend_test; // By Claude on 07/05/2026
cp.fz_inter = this.fz_inter; // By Claude on 07/05/2026
cp.fz_intra = this.fz_intra; // By Claude on 07/05/2026
cp.dc_center = this.dc_center; // By Claude on 07/05/2026
cp.psf_radius = this.psf_radius; cp.psf_radius = this.psf_radius;
cp.n_sigma = this.n_sigma; cp.n_sigma = this.n_sigma;
cp.pyramid = this.pyramid; cp.pyramid = this.pyramid;
......
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