Commit 5961834e authored by Andrey Filippov's avatar Andrey Filippov

Balancing virtual exposure boost/no boost

parent 5f676ce9
...@@ -973,31 +973,36 @@ public class CuasMotion { ...@@ -973,31 +973,36 @@ public class CuasMotion {
params[0] = PAR_PXY; params[0] = PAR_PXY;
} }
// By Claude on 05/24/2026: per-param min/max accumulators (NaN = no data yet)
double[][] minMax = new double[params.length][2];
for (double[] mm : minMax) { mm[0] = Double.NaN; mm[1] = Double.NaN; }
org.json.simple.JSONArray seqResults = new org.json.simple.JSONArray(); org.json.simple.JSONArray seqResults = new org.json.simple.JSONArray();
for (int nseq = nseq0; nseq <= nseq1; nseq++) { for (int nseq = nseq0; nseq <= nseq1; nseq++) {
if (multi_targets[nseq] == null) continue; if (multi_targets[nseq] == null) continue;
org.json.simple.JSONObject seqObj = new org.json.simple.JSONObject(); org.json.simple.JSONObject seqObj = new org.json.simple.JSONObject();
seqObj.put("nseq", nseq); seqObj.put("nseq", nseq);
seqObj.put("title", pvf_titles[0] != null && nseq < pvf_titles[0].length ? pvf_titles[0][nseq] : ""); seqObj.put("title", pvf_titles[0] != null && nseq < pvf_titles[0].length ? pvf_titles[0][nseq] : "");
org.json.simple.JSONArray tilesArr = new org.json.simple.JSONArray(); org.json.simple.JSONArray tilesArr = new org.json.simple.JSONArray();
for (int x = tx; x < Math.min(tx + tw, tilesX); x++) { for (int x = tx; x < Math.min(tx + tw, tilesX); x++) {
for (int y = ty; y < Math.min(ty + th, tilesY); y++) { for (int y = ty; y < Math.min(ty + th, tilesY); y++) {
int ntile = x + y * tilesX; int ntile = x + y * tilesX;
boolean has_targets = (multi_targets[nseq][ntile] != null) && (multi_targets[nseq][ntile].length > 0); boolean has_targets = (multi_targets[nseq][ntile] != null) && (multi_targets[nseq][ntile].length > 0);
if (!has_targets && skip_empty) continue; if (!has_targets && skip_empty) continue;
org.json.simple.JSONObject tileObj = new org.json.simple.JSONObject(); org.json.simple.JSONObject tileObj = new org.json.simple.JSONObject();
tileObj.put("tx", x); tileObj.put("tx", x);
tileObj.put("ty", y); tileObj.put("ty", y);
org.json.simple.JSONArray targsArr = new org.json.simple.JSONArray(); org.json.simple.JSONArray targsArr = new org.json.simple.JSONArray();
if (has_targets) { if (has_targets) {
for (int ntarg = 0; ntarg < multi_targets[nseq][ntile].length; ntarg++) { for (int ntarg = 0; ntarg < multi_targets[nseq][ntile].length; ntarg++) {
if (multi_targets[nseq][ntile][ntarg] == null) continue; if (multi_targets[nseq][ntile][ntarg] == null) continue;
org.json.simple.JSONObject targObj = new org.json.simple.JSONObject(); org.json.simple.JSONObject targObj = new org.json.simple.JSONObject();
for (int npar : params) { for (int pi = 0; pi < params.length; pi++) {
int npar = params[pi];
switch (npar) { switch (npar) {
case PAR_UPXY: case PAR_UPXY:
targObj.put("upx", multi_targets[nseq][ntile][ntarg][CuasMotionLMA.RSLT_FL_PX]); targObj.put("upx", multi_targets[nseq][ntile][ntarg][CuasMotionLMA.RSLT_FL_PX]);
...@@ -1024,7 +1029,12 @@ public class CuasMotion { ...@@ -1024,7 +1029,12 @@ public class CuasMotion {
break; break;
default: default:
if (npar >= 0 && npar < multi_targets[nseq][ntile][ntarg].length) { if (npar >= 0 && npar < multi_targets[nseq][ntile][ntarg].length) {
targObj.put(CuasMotionLMA.LMA_TITLES[npar], multi_targets[nseq][ntile][ntarg][npar]); // By Claude on 05/08/2026 double val = multi_targets[nseq][ntile][ntarg][npar];
targObj.put(CuasMotionLMA.LMA_TITLES[npar], val); // By Claude on 05/08/2026
if (!Double.isNaN(val)) {
if (!(val >= minMax[pi][0])) minMax[pi][0] = val;
if (!(val <= minMax[pi][1])) minMax[pi][1] = val;
}
} }
} }
} }
...@@ -1041,6 +1051,20 @@ public class CuasMotion { ...@@ -1041,6 +1051,20 @@ public class CuasMotion {
} }
} }
res.put("sequences", seqResults); res.put("sequences", seqResults);
// By Claude on 05/24/2026: add min/max for each scalar param
org.json.simple.JSONObject minMaxObj = new org.json.simple.JSONObject();
for (int pi = 0; pi < params.length; pi++) {
int npar = params[pi];
if (npar >= 0 && npar < CuasMotionLMA.LMA_TITLES.length && !Double.isNaN(minMax[pi][0])) {
org.json.simple.JSONObject mmEntry = new org.json.simple.JSONObject();
mmEntry.put("min", minMax[pi][0]);
mmEntry.put("max", minMax[pi][1]);
minMaxObj.put(CuasMotionLMA.LMA_TITLES[npar], mmEntry);
}
}
if (!minMaxObj.isEmpty()) {
res.put("min_max", minMaxObj);
}
} else { } else {
// discover modes // discover modes
...@@ -5902,6 +5926,7 @@ public class CuasMotion { ...@@ -5902,6 +5926,7 @@ public class CuasMotion {
final int when, // set if >=0 for failures final int when, // set if >=0 for failures
final boolean centered, // accum_data was centered, use target_sequence[][][CuasMotionLMA.RSLT_X], target_sequence[][][CuasMotionLMA.RSLT_Y] (if not NaN) final boolean centered, // accum_data was centered, use target_sequence[][][CuasMotionLMA.RSLT_X], target_sequence[][][CuasMotionLMA.RSLT_Y] (if not NaN)
final double boost_exposure, // scale number of accumulated pairs (virtual tracking camera exposure time) final double boost_exposure, // scale number of accumulated pairs (virtual tracking camera exposure time)
final double exposure_boost_factor, // RSLT_A *= pow(boost_exposure, factor); 0.5=sqrt, 0=no scale // By Claude on 05/24/2026
final double [][][] probed_sequence, // contains vector_fields data, single target per tile final double [][][] probed_sequence, // contains vector_fields data, single target per tile
final float [][] accum_data, // should be around 0, no low-freq final float [][] accum_data, // should be around 0, no low-freq
final double lmax_fraction, // 0.7; // Check if local maximum is separated from the surrounding by this fraction of the maximum value final double lmax_fraction, // 0.7; // Check if local maximum is separated from the surrounding by this fraction of the maximum value
...@@ -5944,6 +5969,9 @@ public class CuasMotion { ...@@ -5944,6 +5969,9 @@ public class CuasMotion {
final float [][] accum_debug, final float [][] accum_debug,
final QuadCLT parentCLT, // debug only, maybe null in other cases final QuadCLT parentCLT, // debug only, maybe null in other cases
final int debugLevel){ final int debugLevel){
// Increase relative amplitude of the boosted-exposure maximum to win against non-boosted.
// Why is it needed - compensate blur from mis-registration?
double scale_rslt_a = Math.pow(boost_exposure, exposure_boost_factor); // By Claude on 05/24/2026
// Will not set [RSLT_FAIL] = FAIL_NONE, but it is not final before // Will not set [RSLT_FAIL] = FAIL_NONE, but it is not final before
// apply masking in centered mode // apply masking in centered mode
// final int min_keep = 2; // Keep at least this number of (preliminary) best candidates // final int min_keep = 2; // Keep at least this number of (preliminary) best candidates
...@@ -6310,6 +6338,9 @@ public class CuasMotion { ...@@ -6310,6 +6338,9 @@ public class CuasMotion {
if (rslt >= 0) { if (rslt >= 0) {
cuasMotionLMA.setResult(target); cuasMotionLMA.setResult(target);
target[CuasMotionLMA.RSLT_A] *= scale_rslt_a;
// keep [CuasMotionLMA.RSLT_RMS_A]
if (dbg_img) { // UM-blured-scaled if (dbg_img) { // UM-blured-scaled
dbg_stack [10] = cuasMotionLMA.getFx(); dbg_stack [10] = cuasMotionLMA.getFx();
dbg_stack [11] = cuasMotionLMA.getLastYMinusFx(); dbg_stack [11] = cuasMotionLMA.getLastYMinusFx();
...@@ -9132,6 +9163,7 @@ public class CuasMotion { ...@@ -9132,6 +9163,7 @@ public class CuasMotion {
niter, // final int when, // set if >=0 for failures niter, // final int when, // set if >=0 for failures
centered, // final boolean centered, centered, // final boolean centered,
boost_accum_pairs, // final double boost_exposure, boost_accum_pairs, // final double boost_exposure,
clt_parameters.imp.cuas_exposure_boost_factor, // final double exposure_boost_factor, // By Claude on 05/24/2026
targets_nonoverlap, // final double [][][] vector_fields, // centers targets_nonoverlap, // final double [][][] vector_fields, // centers
fpixels_accumulated, // final double [][] accum_data, // should be around 0, no low-freq fpixels_accumulated, // final double [][] accum_data, // should be around 0, no low-freq
lmax_fraction, // final double cuas_lmax_fraction, // 0.7; // Check if local maximum is separated from tye surrounding by this fraction of the maximum value lmax_fraction, // final double cuas_lmax_fraction, // 0.7; // Check if local maximum is separated from tye surrounding by this fraction of the maximum value
......
...@@ -368,14 +368,9 @@ public class CuasMotionLMA { ...@@ -368,14 +368,9 @@ public class CuasMotionLMA {
Arrays.fill(rslt, Double.NaN); Arrays.fill(rslt, Double.NaN);
return rslt; return rslt;
} }
public double [] getResult() {
double rslt[] = getEmpty();
setResult(rslt);
return rslt;
}
public void setResult(double [] rslt) { public void setResult(
double [] rslt) {
rslt[RSLT_X] = getCenter()[0]; rslt[RSLT_X] = getCenter()[0];
rslt[RSLT_Y] = getCenter()[1]; rslt[RSLT_Y] = getCenter()[1];
// rslt[RSLT_A] = getA(); // rslt[RSLT_A] = getA();
......
...@@ -796,6 +796,7 @@ min_str_neib_fpn 0.35 ...@@ -796,6 +796,7 @@ min_str_neib_fpn 0.35
public double cuas_boost_slow = 4.0; // if >1 and the motion vector is below tile_size/cuas_boost_slow, scale corr_pairs public double cuas_boost_slow = 4.0; // if >1 and the motion vector is below tile_size/cuas_boost_slow, scale corr_pairs
public double cuas_boost_mv_lim = 1.8; // Do not boost if motion vector faster than this (before in code equiv 1.8 pix) public double cuas_boost_mv_lim = 1.8; // Do not boost if motion vector faster than this (before in code equiv 1.8 pix)
public double cuas_boost_accum = 4.0; // if >1 increase tracking camera exposure (TODO: conditional / compete) public double cuas_boost_accum = 4.0; // if >1 increase tracking camera exposure (TODO: conditional / compete)
public double cuas_exposure_boost_factor = 0.5; // exponent: RSLT_A *= pow(boost_exposure, factor); 0.5=sqrt, 0=disabled, 1=linear // By Claude on 05/24/2026
public boolean cuas_phase1_base = true; // Accumulate non-centered targets with base "exposure" public boolean cuas_phase1_base = true; // Accumulate non-centered targets with base "exposure"
public boolean cuas_phase1_boosted = true; // Accumulate non-centered targets with boosted "exposure" public boolean cuas_phase1_boosted = true; // Accumulate non-centered targets with boosted "exposure"
...@@ -2725,6 +2726,8 @@ min_str_neib_fpn 0.35 ...@@ -2725,6 +2726,8 @@ min_str_neib_fpn 0.35
"Do not boost if motion vector faster than this (before in code equiv 1.8 pix)."); "Do not boost if motion vector faster than this (before in code equiv 1.8 pix).");
gd.addNumericField("Increase tracking camera exposure", this.cuas_boost_accum, 5,8,"", gd.addNumericField("Increase tracking camera exposure", this.cuas_boost_accum, 5,8,"",
"If >1 increase tracking camera exposure (later - conditional)."); "If >1 increase tracking camera exposure (later - conditional).");
gd.addNumericField("Exposure boost RSLT_A exponent", this.cuas_exposure_boost_factor, 5,8,"",
"RSLT_A *= pow(boost_exposure, factor). 0.5=sqrt (default), 0=no scale, 1=linear."); // By Claude on 05/24/2026
gd.addCheckbox ("Accumulate phasae 1 base exposure", this.cuas_phase1_base, gd.addCheckbox ("Accumulate phasae 1 base exposure", this.cuas_phase1_base,
"Accumulate non-centered targets (phase 1) with base \"exposure\"."); "Accumulate non-centered targets (phase 1) with base \"exposure\".");
...@@ -4430,6 +4433,7 @@ min_str_neib_fpn 0.35 ...@@ -4430,6 +4433,7 @@ min_str_neib_fpn 0.35
this.cuas_boost_slow = gd.getNextNumber(); this.cuas_boost_slow = gd.getNextNumber();
this.cuas_boost_mv_lim = gd.getNextNumber(); this.cuas_boost_mv_lim = gd.getNextNumber();
this.cuas_boost_accum = gd.getNextNumber(); this.cuas_boost_accum = gd.getNextNumber();
this.cuas_exposure_boost_factor=gd.getNextNumber(); // By Claude on 05/24/2026
this.cuas_phase1_base = gd.getNextBoolean(); this.cuas_phase1_base = gd.getNextBoolean();
this.cuas_phase1_boosted = gd.getNextBoolean(); this.cuas_phase1_boosted = gd.getNextBoolean();
this.cuas_accum_base = gd.getNextBoolean(); this.cuas_accum_base = gd.getNextBoolean();
...@@ -5750,6 +5754,7 @@ min_str_neib_fpn 0.35 ...@@ -5750,6 +5754,7 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_boost_slow", this.cuas_boost_slow+""); // double properties.setProperty(prefix+"cuas_boost_slow", this.cuas_boost_slow+""); // double
properties.setProperty(prefix+"cuas_boost_mv_lim", this.cuas_boost_mv_lim+""); // double properties.setProperty(prefix+"cuas_boost_mv_lim", this.cuas_boost_mv_lim+""); // double
properties.setProperty(prefix+"cuas_boost_accum", this.cuas_boost_accum+""); // double properties.setProperty(prefix+"cuas_boost_accum", this.cuas_boost_accum+""); // double
properties.setProperty(prefix+"cuas_exposure_boost_factor", this.cuas_exposure_boost_factor+""); // double // By Claude on 05/24/2026
properties.setProperty(prefix+"cuas_phase1_base", this.cuas_phase1_base+""); // boolean properties.setProperty(prefix+"cuas_phase1_base", this.cuas_phase1_base+""); // boolean
properties.setProperty(prefix+"cuas_phase1_boosted", this.cuas_phase1_boosted+""); // boolean properties.setProperty(prefix+"cuas_phase1_boosted", this.cuas_phase1_boosted+""); // boolean
properties.setProperty(prefix+"cuas_accum_base", this.cuas_accum_base+""); // boolean properties.setProperty(prefix+"cuas_accum_base", this.cuas_accum_base+""); // boolean
...@@ -7006,6 +7011,7 @@ min_str_neib_fpn 0.35 ...@@ -7006,6 +7011,7 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_boost_slow")!=null) this.cuas_boost_slow=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_slow")); if (properties.getProperty(prefix+"cuas_boost_slow")!=null) this.cuas_boost_slow=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_slow"));
if (properties.getProperty(prefix+"cuas_boost_mv_lim")!=null) this.cuas_boost_mv_lim=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_mv_lim")); if (properties.getProperty(prefix+"cuas_boost_mv_lim")!=null) this.cuas_boost_mv_lim=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_mv_lim"));
if (properties.getProperty(prefix+"cuas_boost_accum")!=null) this.cuas_boost_accum=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_accum")); if (properties.getProperty(prefix+"cuas_boost_accum")!=null) this.cuas_boost_accum=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_accum"));
if (properties.getProperty(prefix+"cuas_exposure_boost_factor")!=null) this.cuas_exposure_boost_factor=Double.parseDouble(properties.getProperty(prefix+"cuas_exposure_boost_factor")); // By Claude on 05/24/2026
if (properties.getProperty(prefix+"cuas_phase1_base")!=null) this.cuas_phase1_base=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_phase1_base")); if (properties.getProperty(prefix+"cuas_phase1_base")!=null) this.cuas_phase1_base=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_phase1_base"));
if (properties.getProperty(prefix+"cuas_phase1_boosted")!=null) this.cuas_phase1_boosted=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_phase1_boosted")); if (properties.getProperty(prefix+"cuas_phase1_boosted")!=null) this.cuas_phase1_boosted=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_phase1_boosted"));
if (properties.getProperty(prefix+"cuas_accum_base")!=null) this.cuas_accum_base=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_accum_base")); if (properties.getProperty(prefix+"cuas_accum_base")!=null) this.cuas_accum_base=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_accum_base"));
...@@ -8279,6 +8285,7 @@ min_str_neib_fpn 0.35 ...@@ -8279,6 +8285,7 @@ min_str_neib_fpn 0.35
imp.cuas_boost_slow = this.cuas_boost_slow; imp.cuas_boost_slow = this.cuas_boost_slow;
imp.cuas_boost_mv_lim = this.cuas_boost_mv_lim; imp.cuas_boost_mv_lim = this.cuas_boost_mv_lim;
imp.cuas_boost_accum = this.cuas_boost_accum; imp.cuas_boost_accum = this.cuas_boost_accum;
imp.cuas_exposure_boost_factor = this.cuas_exposure_boost_factor; // By Claude on 05/24/2026
imp.cuas_phase1_base = this.cuas_phase1_base; imp.cuas_phase1_base = this.cuas_phase1_base;
imp.cuas_phase1_boosted = this.cuas_phase1_boosted; imp.cuas_phase1_boosted = this.cuas_phase1_boosted;
imp.cuas_accum_base = this.cuas_accum_base; imp.cuas_accum_base = this.cuas_accum_base;
......
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