Commit 3cc0997b authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: Row/Col correction (RT step 2): curt rowcol_* dialog params +...

CLAUDE: Row/Col correction (RT step 2): curt rowcol_* dialog params + content-excluded noise calculation

2a: CuasConditioning rowcol_* Config now dialog-driven (curt.rowcol_en/
rowcol_hpf/rowcol_hpf_sigma/rowcol_max_abs/rowcol_outlier, "CUAS RT" tab)
via CuasConditioning.configFromCurt(); RT Row/Col is optional/bypassable
(turn rowcol_en OFF when the FLIR internal correction is verified OK).
Defaults reproduce the previous hardcoded Config bit-exactly
(rowcol_max_abs 0 = the old INFINITY no-gate).

2b: new CorrectionFPN.calculateRowColBackProject() (gated by NEW
imp.cuas_backprop_rowcol, default ON): subtract the back-projected
(pose-transformed, photometric-matched) virtual center from each scene
BEFORE the UM + line averaging, so bright content no longer biases the
row/col averages (the dark horizontal/vertical line artifact). Falls
back to (image - FPN) where the back-projection is undefined; serial
scene loop (GPU back-projection per scene) - borrowed/non-RT path only.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent fa7a57b3
......@@ -26,6 +26,7 @@ package com.elphel.imagej.cuas;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; // By Claude on 07/07/2026
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.cameras.ColorProcParameters;
......@@ -411,16 +412,29 @@ public class CorrectionFPN {
}
}
if (row_col == null) {
boolean cuas_backprop_rowcol = clt_parameters.imp.cuas_backprop_rowcol; // By Claude on 07/07/2026
if (debugLevel >-3) {
System.out.println("Calculating row/column noise per-scene data.");
System.out.println("Calculating row/column noise per-scene data"+
(cuas_backprop_rowcol? " (content-excluded: back-projected center subtracted before line averaging)":"")+".");
}
row_col= CorrectionFPN.calculateRowCol(
quadCLTs, // final QuadCLT [] quadCLTs,
fpn, // final double [][][] fpn, // if null - already applied
fpn_width, // final int width,
cuas_um_sigma, // final double um_sigma,
cuas_max_abs_rowcol, // final double max_abs, // = 100.0;
cuas_outliers_rowcol); // final double weight_outlier // = 0.001;)
row_col= cuas_backprop_rowcol?
CorrectionFPN.calculateRowColBackProject( // By Claude on 07/07/2026 (roadmap RT step 2b)
clt_parameters, // CLTParameters clt_parameters,
center_CLT, // final QuadCLT center_CLT,
quadCLTs, // final QuadCLT [] quadCLTs,
fpn, // final double [][][] fpn, // if null - already applied
fpn_width, // final int width,
cuas_um_sigma, // final double um_sigma,
cuas_max_abs_rowcol, // final double max_abs, // = 100.0;
cuas_outliers_rowcol, // final double weight_outlier // = 0.001;)
debugLevel): // final int debugLevel)
CorrectionFPN.calculateRowCol(
quadCLTs, // final QuadCLT [] quadCLTs,
fpn, // final double [][][] fpn, // if null - already applied
fpn_width, // final int width,
cuas_um_sigma, // final double um_sigma,
cuas_max_abs_rowcol, // final double max_abs, // = 100.0;
cuas_outliers_rowcol); // final double weight_outlier // = 0.001;)
is_new = (row_col != null);
}
center_CLT.getCorrectionFPN().saveShowRowCol(
......@@ -2038,11 +2052,142 @@ public class CorrectionFPN {
}
}
};
}
}
ImageDtt.startAndJoin(threads);
return new double [][][][] {rows,cols};
}
/**
* Content-excluding variant of {@link #calculateRowCol} (roadmap RT step 2b, Andrey's
* plan 07/07/2026): before the UM filter + line averaging, subtract the back-projected
* (pose-transformed into each sensor's frame, photometrically matched) virtual center
* from each scene, so real content no longer biases the row/column averages (the
* bright-spot -> dark row/col line artifact of the UM+gating-only method). Where the
* back-projection is undefined (NaN synth coverage) the plain (image - FPN) value is
* kept - graceful degradation to the legacy behavior there (the line averagers and the
* UM blur are not NaN-safe). The scene loop is SERIAL: each back-projection renders the
* center on the GPU (same single-scene {@link #backPropagate} the FPN calculation uses).
* Slower - the borrowed/non-RT path only. By Claude on 07/07/2026.
*/
public static double [][][][] calculateRowColBackProject(
CLTParameters clt_parameters,
final QuadCLT center_CLT,
final QuadCLT [] quadCLTs,
final double [][][] fpn, // if null - already applied
final int width,
final double um_sigma,
final double max_abs, // = 100.0;
final double weight_outlier, // = 0.001;
final int debugLevel){
// Same back-projection setup as cuasSubtractFpn (geometry/inversion parameters + center disparity)
final int discard_border = clt_parameters.imp.cuas_discard_border;
final double max_fold = clt_parameters.imp.cuas_max_fold;
final int min_in_row_col = clt_parameters.imp.cuas_min_in_row_col;
final int invert_margins = clt_parameters.imp.cuas_invert_margins;
final int invert_iters = clt_parameters.imp.cuas_invert_iters;
final double invert_tolerance = clt_parameters.imp.cuas_invert_tolerance;
final int invert_gap2 = clt_parameters.imp.cuas_invert_gap2;
double [][] ref_combo_dsi = center_CLT.restoreComboDSI(true);
double [] disparity_center= backPrepareCenter(
clt_parameters, // CLTParameters clt_parameters,
center_CLT, // QuadCLT center_CLT,
ref_combo_dsi, // double [][] ref_combo_dsi,
false, // boolean condition_dsi,
-1, // int sensor_mask, // -1 - all;
debugLevel); // int debugLevel)
if (disparity_center == null) {
System.out.println("calculateRowColBackProject(): backPrepareCenter() FAILED - "+
"falling back to calculateRowCol() (no content exclusion)");
return calculateRowCol(quadCLTs, fpn, width, um_sigma, max_abs, weight_outlier);
}
final int num_sens = center_CLT.getNumSensors();
final int height = center_CLT.getTilesY() * center_CLT.getTileSize();
final int num_pix = width * height;
final int num_scenes = quadCLTs.length; // will use all scenes
final int ncolor = 0;
final double [][][] rows = new double[num_scenes][][];
final double [][][] cols = new double[num_scenes][][];
final AtomicLong num_excl = new AtomicLong(0); // pixels with the content estimate subtracted
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int nScene = 0; nScene < num_scenes; nScene++) { // SERIAL over scenes - backPropagate uses the GPU
if (debugLevel > -3) {
System.out.println("calculateRowColBackProject(): back-projecting center into scene "+
nScene+" ("+quadCLTs[nScene].getImageName()+") of "+num_scenes);
}
// diff = source - photometric(back-projected center); the content estimate is (source - diff)
double [][][] diff_weights = backPropagate(
clt_parameters, // CLTParameters clt_parameters,
discard_border, // final int discard_border,
max_fold, // final double max_fold,
min_in_row_col, // final int min_in_row_col,
invert_margins, // final int invert_margins,
invert_gap2, // final int invert_gap2,
invert_iters, // final int invert_iters,
invert_tolerance, // final double invert_tolerance,
center_CLT, // final QuadCLT center_CLT,
quadCLTs[nScene], // final QuadCLT scene_CLT,
disparity_center, // double [] disparity_center
debugLevel-1); // final int debugLevel)
final double [][] diff = (diff_weights != null) ? diff_weights[0] : null;
if (diff == null) {
System.out.println("calculateRowColBackProject(): back-projection FAILED for scene "+
quadCLTs[nScene].getImageName()+" - no content exclusion for this scene");
}
final double [][][] data_chn = new double [num_sens][][];
final boolean sub_fpn = (fpn != null) && (quadCLTs[nScene].getAppliedFPN() != fpn);
final int fScene = nScene;
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsens = ai.getAndIncrement(); nsens < num_sens; nsens = ai.getAndIncrement()) {
double [] raw = quadCLTs[fScene].getImageData()[nsens][ncolor];
double [] df = (diff != null) ? diff[nsens] : null;
double [] img = new double [num_pix];
long ndef = 0;
for (int i = 0; i < num_pix; i++) {
double d = raw[i];
if (sub_fpn) {
d -= fpn[nsens][ncolor][i];
}
if ((df != null) && !Double.isNaN(df[i])) {
d -= raw[i] - df[i]; // subtract the content estimate; keeps (raw - FPN) where undefined
ndef++;
}
img[i] = d;
}
num_excl.addAndGet(ndef);
OpticalFlow.applyUMDouble(
img, // final double [] data,
width, // final int width,
um_sigma, // final double um_sigma,
1.0); // final double um_weight)
data_chn[nsens] = new double [][] {img};
}
}
};
}
ImageDtt.startAndJoin(threads);
rows[fScene] = getRowAvg(
data_chn, // final double [][][] image_data,
width, // final int width,
max_abs, // final double max_abs, // only average within +/- max_abs
weight_outlier); // final double weight_outlier)
cols[fScene] = getColAvg(
data_chn, // final double [][][] image_data,
width, // final int width,
max_abs, // final double max_abs, // only average within +/- max_abs
weight_outlier); // final double weight_outlier)
}
System.out.println(String.format(
"calculateRowColBackProject(): content excluded on %.2f%% of pixels "+
"(%d of %d; elsewhere legacy image-FPN used)",
100.0*num_excl.get()/((double) num_scenes*num_sens*num_pix),
num_excl.get(), (long) num_scenes*num_sens*num_pix));
return new double [][][][] {rows,cols};
}
public static ImagePlus debugFPN(
final QuadCLT [] quadCLTs,
......
......@@ -70,6 +70,23 @@ public class CuasConditioning {
public Config() {}
}
/**
* Build a Config from the curt dialog parameters (roadmap RT step 2a: Row/Col optional/
* tunable - bypass when the FLIR internal correction is verified sufficient). The ONE
* place mapping curt.rowcol_* to Config so all RT ingest call sites stay consistent;
* defaults (rowcol_en=true, max_abs=0->INFINITY) reproduce the previous hardcoded
* Config bit-exactly. By Claude on 07/07/2026, from Andrey's plan.
*/
public static Config configFromCurt(com.elphel.imagej.tileprocessor.CuasRtParameters curt) { // By Claude on 07/07/2026
final Config cfg = new Config();
cfg.rowcol_enable = curt.rowcol_en;
cfg.rowcol_hpf = curt.rowcol_hpf;
cfg.rowcol_hpf_sigma = curt.rowcol_hpf_sigma;
cfg.rowcol_max_abs = (curt.rowcol_max_abs > 0) ? curt.rowcol_max_abs : Double.POSITIVE_INFINITY;
cfg.rowcol_weight_outlier = curt.rowcol_outlier;
return cfg;
}
/**
* Condition all sensors in place.
* @param image_data [sensor][0][pixel] mono LWIR, row-major (idx = y*width + x). Modified in place.
......
......@@ -745,7 +745,7 @@ public class CuasPoseRT {
// at exactly 1 rev period, POSE-10 forensics) and downstream temporal averages turn
// it into content ghosts. ONE constant (CuasRT.appropriateCenter derived it from
// the borrowed center = the average scene). By Claude on 07/05/2026, Andrey's rule.
final CuasConditioning.Config cond_cfg = new CuasConditioning.Config();
final CuasConditioning.Config cond_cfg = CuasConditioning.configFromCurt(clt_parameters.curt); // rowcol_* now dialog-driven (RT step 2a) // By Claude on 07/07/2026
if (clt_parameters.curt.pose_raw) {
cond_cfg.dc_level = CuasRT.sequenceDcLevel(clt_parameters, center_CLT);
if (Double.isNaN(cond_cfg.dc_level)) {
......
......@@ -282,7 +282,7 @@ public class CuasRender {
// temporal averages turn it into content ghosts. ONE constant per sequence
// (CuasRT.appropriateCenter derived it from the borrowed center = the average
// scene). By Claude on 07/05/2026, Andrey's rule.
final CuasConditioning.Config cond_cfg = new CuasConditioning.Config();
final CuasConditioning.Config cond_cfg = CuasConditioning.configFromCurt(clt_parameters.curt); // rowcol_* now dialog-driven (RT step 2a) // By Claude on 07/07/2026
cond_cfg.dc_level = CuasRT.sequenceDcLevel(clt_parameters, center_CLT);
if (Double.isNaN(cond_cfg.dc_level)) {
System.out.println("testRenderSequence(): WARNING - no per-sequence DC level (RT-STATE missing, curt.dc_center==0):"+
......
......@@ -35,6 +35,11 @@ public class CuasRtParameters {
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 center CLT at appropriation (CuasRT initialization) so it matches the zero-sky conditioned scenes (MCLT has no clean DC/AC split - a DC constant costs float32 accuracy). 0 = AUTO: reuse the PER-SEQUENCE value from <center>-RT-STATE.json; when absent, derive as the median of the top (sky) half of the reference buffer render and store it there (erase the file/field to re-derive - the missing-file rule). Nonzero = manual override; this config value is never mutated. Slow targets do not influence this shift. // By Claude on 07/05/2026
public boolean rowcol_en = true; // RT conditioning: subtract per-row/per-column line noise from each raw scene (CuasConditioning). OPTIONAL/bypassable: turn OFF when the FLIR internal row/col correction is verified sufficient (indoor camera test planned) - roadmap RT step 2a (Andrey 07/07/2026). // By Claude on 07/07/2026
public boolean rowcol_hpf = true; // RT conditioning: high-pass the 1-D row/col average profiles before subtracting (preserve low frequencies for the downstream LoG). // By Claude on 07/07/2026
public double rowcol_hpf_sigma = 8.0; // RT conditioning: Gaussian sigma (px) of the profile high-pass, ~ the LoG scale (the noise band the LoG would pass). // By Claude on 07/07/2026
public double rowcol_max_abs = 0.0; // RT conditioning: only average pixels with |value| within this limit (outlier reject, raw pre-photometric counts); 0 = no limit (matches the previous hardcoded INFINITY - gate OFF). // By Claude on 07/07/2026
public double rowcol_outlier = 0.01; // RT conditioning: weight of out-of-range pixels in the line averages (prevents undefined values on all-outlier lines). // By Claude on 07/07/2026
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 int pyramid = 7; // temporal pyramid levels
......@@ -133,6 +138,18 @@ public class CuasRtParameters {
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 at appropriation (match the zero-sky scenes). 0 = AUTO: reuse the per-sequence value from <center>-RT-STATE.json, derive (sky-half median of the reference render) and store there when absent; erase the file/field to re-derive. Nonzero = manual override; this configuration value is never mutated.");
gd.addMessage("=== RT conditioning: Row/Col line noise ==="); // By Claude on 07/07/2026
gd.addCheckbox ("Subtract row/col noise (RT conditioning)", this.rowcol_en, // By Claude on 07/07/2026
"Subtract per-row/per-column line noise from each raw scene during RT conditioning (CuasConditioning). Turn OFF to bypass when the FLIR internal row/column correction is verified sufficient.");
gd.addCheckbox ("Row/col high-pass profiles", this.rowcol_hpf, // By Claude on 07/07/2026
"High-pass the 1-D row/col average profiles before subtracting, preserving the low frequencies for the downstream LoG.");
gd.addNumericField("Row/col high-pass sigma", this.rowcol_hpf_sigma, 3,7,"pix", // By Claude on 07/07/2026
"Gaussian sigma of the profile high-pass, ~ the LoG scale (the noise band the LoG would pass).");
gd.addNumericField("Row/col maximal |value| (0 - no limit)", this.rowcol_max_abs, 3,9,"counts", // By Claude on 07/07/2026
"Only average pixels with |value| within this limit (outlier reject, raw pre-photometric counts). 0 = no limit (previous hardcoded behavior).");
gd.addNumericField("Row/col outlier weight", this.rowcol_outlier, 5,7,"x", // By Claude on 07/07/2026
"Weight of out-of-range pixels in the line averages (prevents undefined values on all-outlier lines).");
gd.addMessage("=== LoG prefilter ===");
gd.addNumericField("Optical PSF radius", this.psf_radius, 6,8,"pix",
"Sensor optical PSF radius for the LoG pre-filter.");
......@@ -275,6 +292,12 @@ public class CuasRtParameters {
this.fz_intra = gd.getNextNumber(); // By Claude on 07/05/2026
this.dc_center = gd.getNextNumber(); // By Claude on 07/05/2026
this.rowcol_en = gd.getNextBoolean(); // By Claude on 07/07/2026
this.rowcol_hpf = gd.getNextBoolean(); // By Claude on 07/07/2026
this.rowcol_hpf_sigma = gd.getNextNumber(); // By Claude on 07/07/2026
this.rowcol_max_abs = gd.getNextNumber(); // By Claude on 07/07/2026
this.rowcol_outlier = gd.getNextNumber(); // By Claude on 07/07/2026
this.psf_radius = gd.getNextNumber();
this.n_sigma = gd.getNextNumber();
// rleak0 getNext removed 2026-06-20 (LReLU now LINEAR); predecessor code at git tag cuas-layer1. // By Claude on 06/20/2026
......@@ -361,6 +384,12 @@ public class CuasRtParameters {
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+"rowcol_en", this.rowcol_en+""); // boolean // By Claude on 07/07/2026
properties.setProperty(prefix+"rowcol_hpf", this.rowcol_hpf+""); // boolean // By Claude on 07/07/2026
properties.setProperty(prefix+"rowcol_hpf_sigma",this.rowcol_hpf_sigma+"");// double // By Claude on 07/07/2026
properties.setProperty(prefix+"rowcol_max_abs", this.rowcol_max_abs+""); // double // By Claude on 07/07/2026
properties.setProperty(prefix+"rowcol_outlier", this.rowcol_outlier+""); // double // By Claude on 07/07/2026
properties.setProperty(prefix+"psf_radius", this.psf_radius+""); // double
properties.setProperty(prefix+"n_sigma", this.n_sigma+""); // double
// rleak0 setProperty removed 2026-06-20 (LReLU now LINEAR); predecessor code at git tag cuas-layer1. // By Claude on 06/20/2026
......@@ -447,6 +476,12 @@ public class CuasRtParameters {
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+"rowcol_en")!=null) this.rowcol_en=Boolean.parseBoolean(properties.getProperty(prefix+"rowcol_en")); // By Claude on 07/07/2026
if (properties.getProperty(prefix+"rowcol_hpf")!=null) this.rowcol_hpf=Boolean.parseBoolean(properties.getProperty(prefix+"rowcol_hpf")); // By Claude on 07/07/2026
if (properties.getProperty(prefix+"rowcol_hpf_sigma")!=null)this.rowcol_hpf_sigma=Double.parseDouble(properties.getProperty(prefix+"rowcol_hpf_sigma"));// By Claude on 07/07/2026
if (properties.getProperty(prefix+"rowcol_max_abs")!=null) this.rowcol_max_abs=Double.parseDouble(properties.getProperty(prefix+"rowcol_max_abs")); // By Claude on 07/07/2026
if (properties.getProperty(prefix+"rowcol_outlier")!=null) this.rowcol_outlier=Double.parseDouble(properties.getProperty(prefix+"rowcol_outlier")); // By Claude on 07/07/2026
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"));
// rleak0 getProperty removed 2026-06-20 (LReLU now LINEAR); predecessor code at git tag cuas-layer1. // By Claude on 06/20/2026
......@@ -535,6 +570,11 @@ public class CuasRtParameters {
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.rowcol_en = this.rowcol_en; // By Claude on 07/07/2026
cp.rowcol_hpf = this.rowcol_hpf; // By Claude on 07/07/2026
cp.rowcol_hpf_sigma = this.rowcol_hpf_sigma; // By Claude on 07/07/2026
cp.rowcol_max_abs = this.rowcol_max_abs; // By Claude on 07/07/2026
cp.rowcol_outlier = this.rowcol_outlier; // By Claude on 07/07/2026
cp.psf_radius = this.psf_radius;
cp.n_sigma = this.n_sigma;
cp.pyramid = this.pyramid;
......
......@@ -761,6 +761,7 @@ min_str_neib_fpn 0.35
public double cuas_min_series = 180.0; // discard shorter series // FIXME: allow shorter, but modify FPN/row_col to copy parent's files if less than cuas_rot_period
public boolean cuas_subtract_rowcol= true; // Subtract row/column noise
public boolean cuas_calc_rowcol= false; // Recalculate+save row/column noise, if false - try to read saved one first
public boolean cuas_backprop_rowcol= true; // exclude content when calculating row/col noise: subtract the back-projected (pose-transformed, photometric-matched) virtual center from each scene before the line averaging - fixes bright content biasing the averages (dark horizontal/vertical lines at bright spots). Slower (one GPU back-projection per scene) - non-RT path only (roadmap RT step 2b, Andrey 07/07/2026). // By Claude on 07/07/2026
public double cuas_um_sigma = 10.0; // Apply Unsharp Mask filter sigma when calculating row/column noise
public double cuas_max_abs_rowcol = 50.0; // consider pixels with abs(UM difference) does not exceed this value
public double cuas_outliers_rowcol = 0.001; // scale weight of the outliers with high difference (to prevent undefined values
......@@ -2694,6 +2695,9 @@ min_str_neib_fpn 0.35
"Subtract per-scene row/column noise (on top of the per scene sequence FPN).");
gd.addCheckbox ("(Re)calculate row/column noise", this.cuas_calc_rowcol,
"Recalculate per-scene row column noise even if it exists. If false, try to read first.");
gd.addCheckbox ("Exclude content (back-project center)", this.cuas_backprop_rowcol, // By Claude on 07/07/2026
"When calculating row/column noise, subtract the back-projected (pose-transformed, photometric-matched) virtual center from each scene before the line averaging - "+
"prevents bright content from biasing the averages (dark row/col lines at bright spots). Slower: one GPU back-projection per scene.");
gd.addNumericField("Row/column unsharp mask filter", this.cuas_um_sigma, 5,7,"pix",
"Apply Unsharp mask filter to the difference between individual scenes and per-sequence FPN before calculating row/column noise.");
gd.addNumericField("Row/column maximal difference", this.cuas_max_abs_rowcol, 5,7,"counts",
......@@ -4464,6 +4468,7 @@ min_str_neib_fpn 0.35
this.cuas_subtract_rowcol = gd.getNextBoolean();
this.cuas_calc_rowcol = gd.getNextBoolean();
this.cuas_backprop_rowcol = gd.getNextBoolean(); // By Claude on 07/07/2026
this.cuas_um_sigma = gd.getNextNumber();
this.cuas_max_abs_rowcol = gd.getNextNumber();
this.cuas_outliers_rowcol = gd.getNextNumber();
......@@ -5799,6 +5804,7 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_subtract_rowcol", this.cuas_subtract_rowcol+"");// boolean
properties.setProperty(prefix+"cuas_calc_rowcol", this.cuas_calc_rowcol+""); // boolean
properties.setProperty(prefix+"cuas_backprop_rowcol",this.cuas_backprop_rowcol+"");// boolean // By Claude on 07/07/2026
properties.setProperty(prefix+"cuas_um_sigma", this.cuas_um_sigma+""); // double
properties.setProperty(prefix+"cuas_max_abs_rowcol", this.cuas_max_abs_rowcol+""); // double
properties.setProperty(prefix+"cuas_outliers_rowcol", this.cuas_outliers_rowcol+"");// double
......@@ -7072,6 +7078,7 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_subtract_rowcol")!=null) this.cuas_subtract_rowcol=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_subtract_rowcol"));
if (properties.getProperty(prefix+"cuas_calc_rowcol")!=null) this.cuas_calc_rowcol=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_calc_rowcol"));
if (properties.getProperty(prefix+"cuas_backprop_rowcol")!=null) this.cuas_backprop_rowcol=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_backprop_rowcol")); // By Claude on 07/07/2026
if (properties.getProperty(prefix+"cuas_um_sigma")!=null) this.cuas_um_sigma=Double.parseDouble(properties.getProperty(prefix+"cuas_um_sigma"));
if (properties.getProperty(prefix+"cuas_max_abs_rowcol")!=null) this.cuas_max_abs_rowcol=Double.parseDouble(properties.getProperty(prefix+"cuas_max_abs_rowcol"));
if (properties.getProperty(prefix+"cuas_outliers_rowcol")!=null) this.cuas_outliers_rowcol=Double.parseDouble(properties.getProperty(prefix+"cuas_outliers_rowcol"));
......@@ -8365,6 +8372,7 @@ min_str_neib_fpn 0.35
imp.cuas_subtract_rowcol = this.cuas_subtract_rowcol;
imp.cuas_calc_rowcol = this.cuas_calc_rowcol;
imp.cuas_backprop_rowcol = this.cuas_backprop_rowcol; // By Claude on 07/07/2026
imp.cuas_um_sigma = this.cuas_um_sigma;
imp.cuas_max_abs_rowcol = this.cuas_max_abs_rowcol;
imp.cuas_outliers_rowcol = this.cuas_outliers_rowcol;
......
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