Commit 29ff9963 authored by Andrey Filippov's avatar Andrey Filippov

tested with boosted exposure

parent 1bf9e9e4
...@@ -31,12 +31,14 @@ import java.io.IOException; ...@@ -31,12 +31,14 @@ import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
...@@ -1685,10 +1687,55 @@ public class CuasMotion { ...@@ -1685,10 +1687,55 @@ public class CuasMotion {
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
return target_sequence; return target_sequence;
} }
/**
* Create initial multi-target array having only single target with motion parameters set up.
* It will be used to select to try instead of the original motion_sequence array using targets[0]
* targets[0][CuasMotionLMA.RSLT_CENTERED] will be initially NaN, set to -1 (CENTERED_USED) after usage
* To prevent re-trying it
* @param motion_sequence
* @return
*/
public static double [][][][] initTargetsFromMotion(
final double [][][] motion_sequence){
final int num_seq = motion_sequence.length;
final int num_tiles = motion_sequence[0].length;
final double [][][][] target_sequence_multi = new double [num_seq][][][];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSeq = ai.getAndIncrement(); nSeq < num_seq; nSeq = ai.getAndIncrement()) {
double [][] mv_tiles = motion_sequence[nSeq];
target_sequence_multi[nSeq] = new double[num_tiles][][];
for (int ntile = 0; ntile < num_tiles; ntile++) {
double [] mv_tile = mv_tiles[ntile];
if (mv_tile != null) {
double [] target = CuasMotionLMA.getEmpty();
target[CuasMotionLMA.RSLT_VX] = mv_tile[CuasMotionLMA.RSLT_VX];
target[CuasMotionLMA.RSLT_VY] = mv_tile[CuasMotionLMA.RSLT_VY];
target[CuasMotionLMA.RSLT_VSTR] = mv_tile[CuasMotionLMA.RSLT_VSTR];
target[CuasMotionLMA.RSLT_VFRAC] = mv_tile[CuasMotionLMA.RSLT_VFRAC];
target[CuasMotionLMA.RSLT_VBOOST] = mv_tile[CuasMotionLMA.RSLT_VBOOST];
target[CuasMotionLMA.RSLT_VCORR] = mv_tile[CuasMotionLMA.RSLT_VCORR];
// target[CuasMotionLMA.RSLT_CENTERED] = Double.NaN; // alreadytCuasMotionLMA.CENTERED_NO;
target_sequence_multi[nSeq][ntile] = new double[][] {target};
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return target_sequence_multi;
}
// By Claude on 05/07/2026: pre-populate target_sequence_multi with FAIL_PENDING sentinels from motion_sequence. // By Claude on 05/07/2026: pre-populate target_sequence_multi with FAIL_PENDING sentinels from motion_sequence.
// Each sentinel is a clone of the motion entry with RSLT_FAIL=FAIL_PENDING, RSLT_CENTERED=CENTERED_NO, // Each sentinel is a clone of the motion entry with RSLT_FAIL=FAIL_PENDING, RSLT_CENTERED=CENTERED_NO,
// RSLT_QSCORE initialized from RSLT_MSCORE. Preserves VX/VY/X/Y and all other motion fields. // RSLT_QSCORE initialized from RSLT_MSCORE. Preserves VX/VY/X/Y and all other motion fields.
@Deprecated
public static void initFromMotionSequence( public static void initFromMotionSequence(
final double [][][] motion_sequence, final double [][][] motion_sequence,
final double [][][][] target_sequence_multi) { final double [][][][] target_sequence_multi) {
...@@ -1709,6 +1756,7 @@ public class CuasMotion { ...@@ -1709,6 +1756,7 @@ public class CuasMotion {
// By Claude on 05/07/2026: after each getEffectiveStrengthMV call, keep RSLT_QSCORE in FAIL_PENDING sentinels // By Claude on 05/07/2026: after each getEffectiveStrengthMV call, keep RSLT_QSCORE in FAIL_PENDING sentinels
// current with the freshly computed RSLT_MSCORE so filter5 ranks by up-to-date motion confidence. // current with the freshly computed RSLT_MSCORE so filter5 ranks by up-to-date motion confidence.
@Deprecated
public static void syncMotionScoreToSentinels( public static void syncMotionScoreToSentinels(
final double [][][] motion_sequence, final double [][][] motion_sequence,
final double [][][][] target_sequence_multi) { final double [][][][] target_sequence_multi) {
...@@ -1719,10 +1767,18 @@ public class CuasMotion { ...@@ -1719,10 +1767,18 @@ public class CuasMotion {
double [] mv = motion_sequence[nSeq][ntile]; double [] mv = motion_sequence[nSeq][ntile];
if (mv != null && target_sequence_multi[nSeq][ntile] != null) { if (mv != null && target_sequence_multi[nSeq][ntile] != null) {
for (double [] entry : target_sequence_multi[nSeq][ntile]) { for (double [] entry : target_sequence_multi[nSeq][ntile]) {
if (entry != null && if ((entry != null) &&
entry[CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_PENDING && ((entry[CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_PENDING) &&
entry[CuasMotionLMA.RSLT_CENTERED] == CuasMotionLMA.CENTERED_NO) { ( entry[CuasMotionLMA.RSLT_CENTERED] == CuasMotionLMA.CENTERED_NO))) {
entry[CuasMotionLMA.RSLT_QSCORE] = mv[CuasMotionLMA.RSLT_MSCORE]; // copy all other
/// entry[CuasMotionLMA.RSLT_QSCORE] = mv[CuasMotionLMA.RSLT_MSCORE]; Why was that needed?
// Make a mrthod to copy all motion-related parameters
entry[CuasMotionLMA.RSLT_VX] = mv[CuasMotionLMA.RSLT_VX];
entry[CuasMotionLMA.RSLT_VY] = mv[CuasMotionLMA.RSLT_VY];
entry[CuasMotionLMA.RSLT_VSTR] = mv[CuasMotionLMA.RSLT_VSTR];
entry[CuasMotionLMA.RSLT_VFRAC] = mv[CuasMotionLMA.RSLT_VFRAC];
entry[CuasMotionLMA.RSLT_VBOOST] = mv[CuasMotionLMA.RSLT_VBOOST];
entry[CuasMotionLMA.RSLT_VCORR] = mv[CuasMotionLMA.RSLT_VCORR];
} }
} }
} }
...@@ -1731,7 +1787,7 @@ public class CuasMotion { ...@@ -1731,7 +1787,7 @@ public class CuasMotion {
} }
// fills out additional fields in target_coords // fills out additional fields in target_coords
@Deprecated
public static double [][] getEffectiveStrengthMV( // calculate tiles effective strength by the motion vectors. Combine with the target LMA? public static double [][] getEffectiveStrengthMV( // calculate tiles effective strength by the motion vectors. Combine with the target LMA?
final double [][][] targets_sequence, final double [][][] targets_sequence,
int niter, // save iteration number on failure if >= int niter, // save iteration number on failure if >=
...@@ -1772,6 +1828,66 @@ public class CuasMotion { ...@@ -1772,6 +1828,66 @@ public class CuasMotion {
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
return effective_strength; return effective_strength;
} }
/**
* When used, each tile has a single target
* @param targets_sequence_multi
* @param niter
* @param tilesX
* @param min_score_mv
* @param speed_min
* @param speed_pref
* @param speed_boost
*/
public static void setEffectiveStrengthMV( // calculate tiles effective strength by the motion vectors. Combine with the target LMA?
final double [][][][] targets_sequence_multi,
int niter, // save iteration number on failure if >=
final int tilesX,
final double min_score_mv,
double speed_min,
double speed_pref,
double speed_boost ){
final int num_seq = targets_sequence_multi.length;
final int num_tiles = targets_sequence_multi[0].length;
// final double [][] effective_strength = new double [num_seq][num_tiles];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSeq = ai.getAndIncrement(); nSeq < num_seq; nSeq = ai.getAndIncrement()) {
double [][][] tile_targets = targets_sequence_multi[nSeq];
for (int ntile = 0; ntile < num_tiles; ntile++) {
double [][] targets = tile_targets[ntile];
if (targets != null) {
for (int ntarg = 0; ntarg < targets.length; ntarg++) {
if (targets[ntarg] != null) {
double es = getEffectiveStrengthMV(
targets[ntarg], // double [] target,
speed_min, // double speed_min,
speed_pref, // double speed_pref,
speed_boost); //double speed_boost)
targets[ntarg][CuasMotionLMA.RSLT_MSCORE] = es;
// effective_strength[nSeq][ntile] = es;
if ((niter >= 0) && !(es >= min_score_mv)) {
targets[ntarg][CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_MOTION;
targets[ntarg][CuasMotionLMA.RSLT_WHEN] = niter;
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return;
}
/* /*
private static void setBadHorizon( private static void setBadHorizon(
...@@ -6553,8 +6669,6 @@ public class CuasMotion { ...@@ -6553,8 +6669,6 @@ public class CuasMotion {
final int num_tiles = target_multi[0].length; final int num_tiles = target_multi[0].length;
final Thread[] threads = ImageDtt.newThreadArray(); final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger adup = new AtomicInteger(0);
final AtomicInteger adup_good = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
...@@ -6577,6 +6691,35 @@ public class CuasMotion { ...@@ -6577,6 +6691,35 @@ public class CuasMotion {
return; return;
} }
public static void setPhase1Score( // Set Phase 1 target index and score (to fine-tune thresholds to reduce false positives
final double [][][][] target_multi) {
final int num_seq = target_multi.length;
final int num_tiles = target_multi[0].length;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSeq = ai.getAndIncrement(); nSeq < num_seq; nSeq = ai.getAndIncrement()) {
for (int ntile = 0; ntile < num_tiles; ntile++) {
double [][] targets = target_multi[nSeq][ntile];
if (targets != null){
for (int ntarg = 0; ntarg <targets.length; ntarg++) {
targets[ntarg][CuasMotionLMA.RSLT_PHASE1_INDEX] = ntarg;
targets[ntarg][CuasMotionLMA.RSLT_PHASE1_SCORE] = targets[ntarg][CuasMotionLMA.RSLT_QSCORE];
targets[ntarg][CuasMotionLMA.RSLT_PHASE1_AMP] = targets[ntarg][CuasMotionLMA.RSLT_A];
targets[ntarg][CuasMotionLMA.RSLT_PHASE1_MSCORE] = targets[ntarg][CuasMotionLMA.RSLT_MSCORE];
targets[ntarg][CuasMotionLMA.RSLT_PHASE1_VSTR] = targets[ntarg][CuasMotionLMA.RSLT_VSTR];
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return;
}
...@@ -7831,6 +7974,9 @@ public class CuasMotion { ...@@ -7831,6 +7974,9 @@ public class CuasMotion {
int precorr_ra = clt_parameters.imp.cuas_precorr_ra; // By Claude on 05/07/2026 int precorr_ra = clt_parameters.imp.cuas_precorr_ra; // By Claude on 05/07/2026
int accum_ra = clt_parameters.imp.cuas_accum_ra; // By Claude on 05/07/2026: LPF for shiftAndRenderAccumulate int accum_ra = clt_parameters.imp.cuas_accum_ra; // By Claude on 05/07/2026: LPF for shiftAndRenderAccumulate
boolean cuas_gaussian_ra = clt_parameters.imp.cuas_gaussian_ra; // By Claude on 05/07/2026 boolean cuas_gaussian_ra = clt_parameters.imp.cuas_gaussian_ra; // By Claude on 05/07/2026
boolean phase1_boosted = clt_parameters.imp.cuas_phase1_boosted;// By AF on 05/12/2026
// at least one of phase1_boosted, phase1_base should be used, normally both
boolean phase1_base = clt_parameters.imp.cuas_phase1_base || !phase1_boosted; // By AF on 05/12/2026
boolean accum_boosted = clt_parameters.imp.cuas_accum_boosted;// By AF on 05/12/2026 boolean accum_boosted = clt_parameters.imp.cuas_accum_boosted;// By AF on 05/12/2026
// at least one of accum_boosted, accum_base should be used, normally both // at least one of accum_boosted, accum_base should be used, normally both
boolean accum_base = clt_parameters.imp.cuas_accum_base || !accum_boosted; // By AF on 05/12/2026 boolean accum_base = clt_parameters.imp.cuas_accum_base || !accum_boosted; // By AF on 05/12/2026
...@@ -7905,14 +8051,41 @@ public class CuasMotion { ...@@ -7905,14 +8051,41 @@ public class CuasMotion {
if (target_sequence_multi == null) { if (target_sequence_multi == null) {
// final double [][][][] // final double [][][][]
target_sequence_multi = new double [num_seq][num_tiles][][]; // target_sequence_multi = new double [num_seq][num_tiles][][];
initFromMotionSequence(motion_sequence, target_sequence_multi); // By Claude on 05/07/2026 // initFromMotionSequence(motion_sequence, target_sequence_multi); // By Claude on 05/07/2026
target_sequence_multi = initTargetsFromMotion(motion_sequence);
// Calculate and set motion vectors strengths/failures
setEffectiveStrengthMV( // calculate tiles effective strength by the motion vectors. Combine with the target LMA?
target_sequence_multi, // final double [][][] motion_scan,
niter, // int niter, // save iteration number on failure if >=
cuasMotion.tilesX, // final int tilesX)
// Let them fail here and not be considered at all
min_score_mv, // 0, // final double min_score_mv,
speed_min, // double speed_min,
speed_pref, // double speed_pref,
speed_boost); // double speed_boost);
// first pass, using non-centered targets // first pass, using non-centered targets
// double boost_accum_pairs = slow_mode? 1.0:4.0; // just for testing, unconditionally boost tracking cameras exposure time // double boost_accum_pairs = slow_mode? 1.0:4.0; // just for testing, unconditionally boost tracking cameras exposure time
for (; niter < num_cycles; niter++) { for (; niter < num_cycles; niter++) {
boolean save_filtered_low = intermed_low && (niter < iter_show); boolean save_filtered_low = intermed_low && (niter < iter_show);
boolean save_filtered_high = intermed_high && (niter < iter_show); boolean save_filtered_high = intermed_high && (niter < iter_show);
totals = getRemain(target_sequence_multi, num_all, num_undef, num_good, num_bad); // By Claude on 05/07/2026 totals = getRemain(
target_sequence_multi, // final double [][][][] target_sequence_multi,
num_all, // int [] num_all_in,
num_undef, // int [] num_motion_undef_in, // if non-null, will use it instead of num_noncentered_in // AF 05/20/2026
// next will be ignored if num_motion_undef_in != null
null, // int [] num_noncentered_in,
num_good, // int [] num_good_in,
num_bad); // int [] num_bad_in)
// for motion-based selection true undefined is
if (debugLevel > -4) {
for (int i = 0; i <totals.length; i++) {
System.out.print(" totals["+i+"]="+totals[i]);
}
System.out.println();
}
if (totals[TOTALS_UNDEFINED] == 0) { if (totals[TOTALS_UNDEFINED] == 0) {
if (debugLevel > -4) System.out.println ("No undefined tiles left, breaking loop"); if (debugLevel > -4) System.out.println ("No undefined tiles left, breaking loop");
break; break;
...@@ -7931,6 +8104,8 @@ public class CuasMotion { ...@@ -7931,6 +8104,8 @@ public class CuasMotion {
// ==== does it need to be re-calculated ? ===== // ==== does it need to be re-calculated ? =====
// Only used in int [][] filter5 = filter5Targets( // will ignore failed tiles // Only used in int [][] filter5 = filter5Targets( // will ignore failed tiles
// for centered tile pass, trying to eliminate with null for the motion sequence // for centered tile pass, trying to eliminate with null for the motion sequence
// Not needed - set once above
/*
getEffectiveStrengthMV( // calculate tiles effective strength by the motion vectors. Combine with the target LMA? getEffectiveStrengthMV( // calculate tiles effective strength by the motion vectors. Combine with the target LMA?
motion_sequence, // final double [][][] motion_scan, motion_sequence, // final double [][][] motion_scan,
niter, // int niter, // save iteration number on failure if >= niter, // int niter, // save iteration number on failure if >=
...@@ -7940,7 +8115,8 @@ public class CuasMotion { ...@@ -7940,7 +8115,8 @@ public class CuasMotion {
speed_pref, // double speed_pref, speed_pref, // double speed_pref,
speed_boost); // double speed_boost); speed_boost); // double speed_boost);
syncMotionScoreToSentinels(motion_sequence, target_sequence_multi); // By Claude on 05/07/2026 syncMotionScoreToSentinels(motion_sequence, target_sequence_multi); // By Claude on 05/07/2026
*/
/*
if (save_filtered_low && debug_more) { if (save_filtered_low && debug_more) {
ImagePlus imp_mv_strength = showTargetSequence( ImagePlus imp_mv_strength = showTargetSequence(
motion_sequence, // double [][][] vector_fields_sequence, motion_sequence, // double [][][] vector_fields_sequence,
...@@ -7950,16 +8126,30 @@ public class CuasMotion { ...@@ -7950,16 +8126,30 @@ public class CuasMotion {
cuasMotion.tilesX); // int tilesX) { cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_mv_strength); parentCLT.saveImagePlusInModelDirectory(imp_mv_strength);
} }
*/
if (save_filtered_low && debug_more) {
String title = model_prefix+"-PRE-SELECT-n"+niter;
ImagePlus imp_pre_select = showTargetSequence(
target_sequence_multi, // double [][][] vector_fields_sequence,
slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
title, // model_prefix+"-ADDED_NEW_MULTI-n"+niter,// String title,
false, // good_only, // final boolean good_only,
true, // show_empty, // final boolean show_empty, // show scenes with no (valid) targets
!batch_mode, // boolean show,
cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_pre_select); // ImagePlus imp)
}
int [][] filter5 = filter5Targets( // will ignore failed tiles int [][] filter5 = filter5Targets( // will ignore failed tiles
null, // By Claude on 05/07/2026: use FAIL_PENDING sentinels in target_sequence_multi // null, // By Claude on 05/07/2026: use FAIL_PENDING sentinels in target_sequence_multi
target_sequence_multi, // final double [][][][] target_sequence_multi, target_sequence_multi, // final double [][][][] target_sequence_multi,
// if use motion and select_new will only consider tiles (and compare motion scores in motion_sequence) that have nulls in target_sequence_multi[nseq][ntile] // if use motion and select_new will only consider tiles (and compare motion scores in motion_sequence) that have nulls in target_sequence_multi[nseq][ntile]
// if not use motion and select_new will only consider (and compare scores) tiles that have [RSLT_CENTERED] = 0.0 // if not use motion and select_new will only consider (and compare scores) tiles that have [RSLT_CENTERED] = 0.0
// if not select_new (assumes not use motion) will return best (and good) target indices // if not select_new (assumes not use motion) will return best (and good) target indices
true, // final boolean use_motion, // true - use motion vectors confidence, false - use target confidence true, // final boolean use_motion, // true - use motion vectors confidence, false - use target confidence
true, // final boolean select_new, // true - use only untested tiles, false - use good tiles true, // final boolean select_new, // true - use only untested tiles, false - use good tiles
min_score_mv, // double min_confidence, // min_score_mv already applied
0, // min_score_mv, // double min_confidence,
target_horizon, // final double lma_horizon, // target below horizon target_horizon, // final double lma_horizon, // target below horizon
cuasMotion.tilesX, // final int tilesX, cuasMotion.tilesX, // final int tilesX,
max_range, // final int range, // 1 or 2 max_range, // final int range, // 1 or 2
...@@ -8001,7 +8191,6 @@ public class CuasMotion { ...@@ -8001,7 +8191,6 @@ public class CuasMotion {
null); // remain); // final int [] remain) null); // remain); // final int [] remain)
if (save_filtered_low && debug_more) { if (save_filtered_low && debug_more) {
// targets_nonoverlap will contain motion vectors used fro the next fpixels_accumulated // targets_nonoverlap will contain motion vectors used fro the next fpixels_accumulated
ImagePlus imp_novl = showTargetSequence( ImagePlus imp_novl = showTargetSequence(
targets_nonoverlap, // double [][][] vector_fields_sequence, targets_nonoverlap, // double [][][] vector_fields_sequence,
...@@ -8021,210 +8210,240 @@ public class CuasMotion { ...@@ -8021,210 +8210,240 @@ public class CuasMotion {
// show good and bad accumulated here too? // show good and bad accumulated here too?
} }
// perform new accumulations of shifted non-conflicting tiles // Try both boosted and non-boosted
float [][] fpixels_accumulated = cuasMotion.shiftAndRenderAccumulate( int num_new = 0;
clt_parameters, // CLTParameters clt_parameters, // double effective_boost = boost_accum_pairs; // default virtual exposure scale
false, // final boolean center, if (phase1_boosted) {
false, // final boolean fill_zeros, double [][][][] targets_new_multi=getNewTargets(
fpixels_accum, // By Claude on 05/07/2026: LPF'd with accum_ra (was fpixels_tum) false, // boolean centered,
extended_scan, // final double [][][] vector_field, clt_parameters, // CLTParameters clt_parameters,
frame0, // final int frame0, // for vector_field[0] cuasMotion, // CuasMotion cuasMotion,
corr_inc, // final int frame_step, fpixels_accum, // float [][] fpixels_accum,
half_accum_range, // final int half_range, targets_nonoverlap, // double [][][] targets_nonoverlap,
boost_accum_pairs,// final double boost_pairs, extended_scan, // double [][][] extended_scan,
smooth, // final boolean smooth, frame0, // int frame0,
corr_offset, // final int corr_offset, // interframe distance for correlation corr_inc, // int corr_inc,
true); // final boolean batch_mode) { half_accum_range, // int half_accum_range,
if (save_filtered_high) { boost_accum_pairs, // boost_accum_pairs, // double boost_accum_pairs,
String title = model_prefix+"-ACCUMULATED-n"+niter; smooth, // boolean smooth,
if (boost_accum_pairs > 1.0) { corr_offset, // int corr_offset, // interframe distance for correlation
title+="-BOOST"+boost_accum_pairs; save_filtered_high, // boolean save_filtered_high,
model_prefix, // String model_prefix,
niter, // int niter,
input_range, // double input_range,
lmax_fraction, // double lmax_fraction,
lmax_flt_neglim, // double lmax_flt_neglim,
lmax_flt_hsigma, // double lmax_flt_hsigma,
lmax_flt_lsigma, // double lmax_flt_lsigma,
lmax_flt_scale, // double lmax_flt_scale,
sky_threshold, // double sky_threshold,
target_horizon, // double target_horizon,
filter_below_horizon, // double filter_below_horizon,
lmax_hack_ridge, // double lmax_hack_ridge,
lmax_radius, // double lmax_radius,
centered_radius, // lmax_radius, // double centered_radius,
centered_blur, // 0.5, // double centered_radius_blur,
duplicate_tolerance, // 1.0, // double pix_tolerance, //
target_radius, // double target_radius,
n_recenter, // int n_recenter,
no_border, // boolean no_border,
// Moving target LMA
lma_sigma, // double lma_sigma,
wnd_pedestal, // double wnd_pedestal,
lma_r0, // double lma_r0,
lma_ovrsht, // double lma_ovrsht,
// CUAS Motion LMA // // CUAS Motion LMA parameters
lma_fit_xy, // boolean lma_fit_xy,
lma_fit_a, // boolean lma_fit_a,
lma_fit_c, // boolean lma_fit_c,
lma_fit_r, // boolean lma_fit_r,
lma_fit_k, // boolean lma_fit_k,
lambda, // double lambda,
lambda_good, // double lambda_good,
lambda_bad, // double lambda_bad,
lambda_max, // double lambda_max,
rms_diff, // double rms_diff,
num_iter, // int num_iter,
min_keep, // int min_keep,
save_filtered_low, // boolean save_filtered_low,
debug_more, // boolean debug_more,
good_only, // boolean good_only,
show_empty, // boolean show_empty,
num_corr_samples, // int num_corr_samples,
target_strength, // double target_strength,
target_frac, // double [][] target_frac,
lma_rms, // double lma_rms,
lma_arms, // double lma_arms,
lma_pre_mina, // double lma_pre_mina,
// use lma_mina2, lma_rrms2 !
lma_mina, // double lma_mina,
lma_rrms, // double lma_rrms,
lma_maxr, // double lma_maxr,
lma_minr1, // double lma_minr1,
lma_mink, // double lma_mink,
lma_maxk, // double lma_maxk,
lma_a2a, // double lma_a2a,
slow_fast_mismatch, // double slow_fast_mismatch,
fail_mismatch, // boolean fail_mismatch,
offcenter, // double offcenter,
noisemax, // double noisemax,
factor_lim, // double factor_lim,
factor_pow, // double factor_pow,
score_coeff, // double [] score_coeff,
slow_score, // double slow_score,
batch_mode, // boolean batch_mode,
debugLevel); // int debugLevel);
num_new += addNewResults(
target_sequence_multi, // final double [][][] target_sequence, // will only process non-nulls here
targets_new_multi, // final double [][][] new_sequence,
0, // final int num_best, // if >0, limit number of best results to add
niter, // final int when_iter,
debugLevel); // final int debugLevel);
if (debugLevel > -4) {
System.out.println("Added "+num_new+" new tiles as good/bad with BOOST="+boost_accum_pairs);
} }
ImagePlus imp_acc = ShowDoubleFloatArrays.makeArrays( if (save_filtered_low) {
fpixels_accumulated, // double[][] pixels, String title = model_prefix+"-ADDED_NEW_MULTI-n"+niter;
cuasMotion.gpu_max_width, if (boost_accum_pairs > 1.0) {
cuasMotion.gpu_max_height, title+="-BOOST"+boost_accum_pairs;
title, // model_prefix+"-ACCUMULATED-n"+niter, // String title, }
slice_titles); ImagePlus imp_new_scores = showTargetSequence(
imp_acc.getProcessor().setMinAndMax(-input_range/2, input_range/2); target_sequence_multi, // double [][][] vector_fields_sequence,
if (!batch_mode) { slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
imp_acc.show(); title, // model_prefix+"-ADDED_NEW_MULTI-n"+niter,// String title,
good_only, // final boolean good_only,
show_empty, // final boolean show_empty, // show scenes with no (valid) targets
!batch_mode, // boolean show,
cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_new_scores); // ImagePlus imp)
} }
parentCLT.saveImagePlusInModelDirectory(imp_acc); // ImagePlus imp)
} }
// replace center frames with the accumulated ones if (phase1_base) {
if (debugLevel > -4) { double [][][][] targets_new_multi=getNewTargets(
System.out.println("Starting render, iteration = "+niter); false, // boolean centered,
} clt_parameters, // CLTParameters clt_parameters,
cuasMotion, // CuasMotion cuasMotion,
// show just fpixels_accumulated fpixels_accum, // float [][] fpixels_accum,
// move outside? compare to slice_titles known targets_nonoverlap, // double [][][] targets_nonoverlap,
// Calculate both centroid and LMA target parametes, return both extended_scan, // double [][][] extended_scan,
// targets_new will contain motion vectors, centroid, and LMA results combined frame0, // int frame0,
//save_filtered_high corr_inc, // int corr_inc,
float [][] accum_debug = save_filtered_high? new float [num_corr_samples][]:null; //fpixels_accumulated.length] half_accum_range, // int half_accum_range,
boolean keep_failed = false; // keep failed targets 1.0, // boost_accum_pairs, // boost_accum_pairs, // double boost_accum_pairs,
double [][][][] targets_new_multi = getAccumulatedCoordinatesMulti( smooth, // boolean smooth,
keep_failed, // final boolean keep_failed, // keep failed targets corr_offset, // int corr_offset, // interframe distance for correlation
niter, // final int when, // set if >=0 for failures save_filtered_high, // boolean save_filtered_high,
false, // final boolean centered, model_prefix, // String model_prefix,
boost_accum_pairs, // final double boost_exposure, niter, // int niter,
targets_nonoverlap, // final double [][][] vector_fields, // centers input_range, // double input_range,
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, // double lmax_fraction,
lmax_flt_neglim, // final double lmax_flt_neglim, // -0.3; // limit negative data to reduce ridge influence (make -10 to disable) lmax_flt_neglim, // double lmax_flt_neglim,
lmax_flt_hsigma, // final double lmax_flt_hsigma, // 1.0 // HPF (~UM) subtract GB with this sigma from the data tile lmax_flt_hsigma, // double lmax_flt_hsigma,
lmax_flt_lsigma, // final double lmax_flt_lsigma, // 1.0 // LPF - GB result of the previous subtraction lmax_flt_lsigma, // double lmax_flt_lsigma,
lmax_flt_scale, // final double lmax_flt_scale, // 5.0 // scale filtering result lmax_flt_scale, // double lmax_flt_scale,
cuasMotion.sky_mask, // final double sky_mask, sky_threshold, // double sky_threshold,
sky_threshold, // final double sky_threshold, // 0.9 // minimal value of the sky mask where target is possible target_horizon, // double target_horizon,
target_horizon+filter_below_horizon, // final double lma_horizon, filter_below_horizon, // double filter_below_horizon,
lmax_hack_ridge, // final double lmax_hack_ridge, // 0.45; // Hack for ridges: remove horizontal streaks, where average(abs()) for the line exceeds fraction of abs max 0.32-good, 0.55 - bad lmax_hack_ridge, // double lmax_hack_ridge,
lmax_radius, // final int cuas_lmax_radius, // 3; // look inside cuas_lmax_radius* 2 + 1 square for the local maximum isolation lmax_radius, // double lmax_radius,
centered_radius, // final double centered_radius,
centered_blur, // final double centered_radius_blur, centered_radius, // lmax_radius, // double centered_radius,
duplicate_tolerance, // final double pix_tolerance, // centered_blur, // 0.5, // double centered_radius_blur,
// lmax_zero, // final boolean cuas_lmax_zero, // true; // zero all data outside this radius from the maximum duplicate_tolerance, // 1.0, // double pix_tolerance, //
target_radius, // final double centroid_radius,
n_recenter, // final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass) target_radius, // double target_radius,
cuasMotion.tilesX, // final int tilesX){ n_recenter, // int n_recenter,
no_border, // final boolean no_border, no_border, // boolean no_border,
// Moving target LMA // Moving target LMA
lma_sigma, // final double lma_sigma, lma_sigma, // double lma_sigma,
wnd_pedestal, // final double wnd_pedestal, wnd_pedestal, // double wnd_pedestal,
lma_r0, // final double lma_r0, lma_r0, // double lma_r0,
lma_ovrsht, // final double lma_ovrsht, lma_ovrsht, // double lma_ovrsht,
// CUAS Motion LMA parameters // CUAS Motion LMA // // CUAS Motion LMA parameters
lma_fit_xy, // final boolean lma_fit_xy, lma_fit_xy, // boolean lma_fit_xy,
lma_fit_a, // final boolean lma_fit_a, lma_fit_a, // boolean lma_fit_a,
lma_fit_c, // final boolean lma_fit_c, lma_fit_c, // boolean lma_fit_c,
lma_fit_r, // final boolean lma_fit_r, lma_fit_r, // boolean lma_fit_r,
lma_fit_k, // final boolean lma_fit_k, lma_fit_k, // boolean lma_fit_k,
lambda, // final double lambda, lambda, // double lambda,
lambda_good, // final double lambda_good, lambda_good, // double lambda_good,
lambda_bad, // final double lambda_bad, lambda_bad, // double lambda_bad,
lambda_max, // final double lambda_max, lambda_max, // double lambda_max,
rms_diff, // final double rms_diff, rms_diff, // double rms_diff,
num_iter, // final int num_iter,0, // final double pre_min_a, // pre-filter minimal LMA-A (half finbal?) num_iter, // int num_iter,
lma_pre_mina * lma_mina,// final double pre_min_a, // 0.5 //scale cuas_lma_mina to filter initial candidates (if there are > one of them) min_keep, // int min_keep,
min_keep, // final int min_keep, // 2; // keep at least this number of candidates before using cuas_lma_pre_mina filter save_filtered_low, // boolean save_filtered_low,
accum_debug, // final float [][] accum_debug, debug_more, // boolean debug_more,
parentCLT, // final QuadCLT parentCLT, // debug only, maybe null in other cases good_only, // boolean good_only,
debugLevel); // final int debugLevel); show_empty, // boolean show_empty,
num_corr_samples, // int num_corr_samples,
if (accum_debug != null) { target_strength, // double target_strength,
String title = model_prefix+"-ACCUMULATED_FILTERED-MULTI-n"+niter; target_frac, // double [][] target_frac,
if (boost_accum_pairs > 1.0) { lma_rms, // double lma_rms,
title+="-BOOST"+boost_accum_pairs; lma_arms, // double lma_arms,
lma_pre_mina, // double lma_pre_mina,
// use lma_mina2, lma_rrms2 !
lma_mina, // double lma_mina,
lma_rrms, // double lma_rrms,
lma_maxr, // double lma_maxr,
lma_minr1, // double lma_minr1,
lma_mink, // double lma_mink,
lma_maxk, // double lma_maxk,
lma_a2a, // double lma_a2a,
slow_fast_mismatch, // double slow_fast_mismatch,
fail_mismatch, // boolean fail_mismatch,
offcenter, // double offcenter,
noisemax, // double noisemax,
factor_lim, // double factor_lim,
factor_pow, // double factor_pow,
score_coeff, // double [] score_coeff,
slow_score, // double slow_score,
batch_mode, // boolean batch_mode,
debugLevel); // int debugLevel);
num_new += addNewResults(
target_sequence_multi, // final double [][][] target_sequence, // will only process non-nulls here
targets_new_multi, // final double [][][] new_sequence,
0, // final int num_best, // if >0, limit number of best results to add
niter, // final int when_iter,
debugLevel); // final int debugLevel);
if (debugLevel > -4) {
System.out.println("Added "+num_new+" new tiles as good/bad, base (no boost mode)");
} }
ImagePlus imp_acc = ShowDoubleFloatArrays.makeArrays( if (save_filtered_low) {
accum_debug, // double[][] pixels, String title = model_prefix+"-ADDED_NEW_MULTI-n"+niter;
cuasMotion.gpu_max_width, ImagePlus imp_new_scores = showTargetSequence(
cuasMotion.gpu_max_height, target_sequence_multi, // double [][][] vector_fields_sequence,
title, // model_prefix+"-ACCUMULATED_FILTERED-MULTI-n"+niter, // String title, slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
slice_titles); title, // model_prefix+"-ADDED_NEW_MULTI-n"+niter,// String title,
imp_acc.getProcessor().setMinAndMax(-input_range/2, input_range/2); good_only, // final boolean good_only,
if (!batch_mode) { show_empty, // final boolean show_empty, // show scenes with no (valid) targets
imp_acc.show(); !batch_mode, // boolean show,
cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_new_scores); // ImagePlus imp)
} }
parentCLT.saveImagePlusInModelDirectory(imp_acc); // ImagePlus imp)
} }
if (save_filtered_low && debug_more) { if (num_new == 0) { // total for boost/no-boost
String title = model_prefix+"-NEW-TARGETS-MULTI-n"+niter;
if (boost_accum_pairs > 1.0) {
title+="-BOOST"+boost_accum_pairs;
}
ImagePlus imp_new = showTargetSequence(
targets_new_multi, // final double [][][][] targets_multi,
slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
title, // model_prefix+"-NEW-TARGETS-MULTI-n"+niter,// String title,
good_only, // final boolean good_only,
show_empty, // final boolean show_empty, // show scenes with no (valid) targets
!batch_mode, // boolean show,
cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_new); // ImagePlus imp)
}
// evaluate scores here to reduce the number of attempts for centered targets
getEffectiveStrengthLMA(
targets_new_multi, // final double [][][] target_coords, // LMA
target_strength, // final double target_strength,
target_frac, // final double [][] target_frac, // pairs - strength, minimal fraction for that strength
lma_rms, // final double lma_rms, // = 1.5; // Maximal RMS (should always match, regardless if A)
lma_arms, // final double lma_arms, // = 0.06; // Maximal absolute RMS (should match one of cuas_lma_arms OR cuas_lma_rrms (0.484)
lma_rrms, // final double lma_rrms, // = 0.15; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
lma_mina, // final double lma_mina, // = 1.0; // Minimal A (amplitude)
lma_maxr, // final double lma_maxr, // = 5.0; // Minimal K (overshoot) = 3.0
lma_minr1, // final double lma_minr1,// = 1.0; // Minimal R1 (radius of positive peak)
lma_mink, // final double lma_mink, // = 0.0; // Minimal K (overshoot) = 1.0
lma_maxk, // final double lma_maxk, // = 5.0; // Minimal K (overshoot) = 3.0// final double lma_a2a,
lma_a2a, // final double lma_a2a,
0, // max_mismatch, // final double max_mismatch, apply only during final, when mismatch scores are calculated
slow_fast_mismatch,// final double slow_fast_mismatch, // // 1.5; allow larger mismatch between slow and fast
fail_mismatch, // final boolean fail_mismatch,
offcenter, // final double offcenter,
cuasMotion.getNoiseNeibs(), // final int [] noise_neibs,
// cuasMotion.getNoiseMap(), // final double [] noise_map,
// noisemax, // final double noise_max,
target_horizon, // final double lma_horizon, // horizon as maximal pixel Y
cuasMotion.tilesX); // final int tilesX,
getScore(
targets_new_multi, // final double [][][] target_sequence, // modifies certain fields (scores)
factor_lim, // final double importance_limit,
factor_pow, // final double importance_power, // Raise each factor to this power before combining
score_coeff, // final double [] importance, // for now (each - squared?): [0] - Amplitude (A/A0), 1 - RMS (RMS0/RMS), 2 - RRMS((RMS/A0) / (RMS/A)
slow_score, // final double slow_score, // multiply total score for targets detected in slow target mode
cuasMotion.tilesX); // final int tilesX,
if (save_filtered_low) {
String title = model_prefix+"-NEW-TARGETS_SCORES_MULTI-n"+niter;
if (boost_accum_pairs > 1.0) {
title+="-BOOST"+boost_accum_pairs;
}
ImagePlus imp_new_scores = showTargetSequence(
targets_new_multi, // double [][][] vector_fields_sequence,
slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
title, // model_prefix+"-NEW-TARGETS_SCORES_MULTI-n"+niter,// String title,
good_only, // final boolean good_only,
show_empty, // final boolean show_empty, // show scenes with no (valid) targets
!batch_mode, // boolean show,
cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_new_scores); // ImagePlus imp)
}
int num_new = addNewResults(
target_sequence_multi, // final double [][][] target_sequence, // will only process non-nulls here
targets_new_multi, // final double [][][] new_sequence,
0, // final int num_best, // if >0, limit number of best results to add
niter, // final int when_iter,
debugLevel); // final int debugLevel);
if (debugLevel > -4) {
System.out.println("Added "+num_new+" new tiles as good/bad");
}
if (save_filtered_low) {
String title = model_prefix+"-ADDED_NEW_MULTI-n"+niter;
if (boost_accum_pairs > 1.0) {
title+="-BOOST"+boost_accum_pairs;
}
ImagePlus imp_new_scores = showTargetSequence(
target_sequence_multi, // double [][][] vector_fields_sequence,
slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
title, // model_prefix+"-ADDED_NEW_MULTI-n"+niter,// String title,
good_only, // final boolean good_only,
show_empty, // final boolean show_empty, // show scenes with no (valid) targets
!batch_mode, // boolean show,
cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_new_scores); // ImagePlus imp)
}
if (num_new == 0) {
if (debugLevel > -4) System.out.println ("Nothing added from last try, breaking the loop.\n"); if (debugLevel > -4) System.out.println ("Nothing added from last try, breaking the loop.\n");
break; // breaks here break; // breaks here
} }
totals = getRemain(target_sequence_multi, num_all, num_undef, num_good, num_bad); // By Claude on 05/07/2026 totals = getRemain(
target_sequence_multi, // final double [][][][] target_sequence_multi,
num_all, // int [] num_all_in,
num_undef, // int [] num_motion_undef_in, // if non-null, will use it instead of num_noncentered_in // AF 05/20/2026
// next will be ignored if num_motion_undef_in != null
null, // int [] num_noncentered_in,
num_good, // int [] num_good_in,
num_bad); // int [] num_bad_in)
if (debugLevel > -4) printStats ("After iteration "+niter, true, num_all, num_undef, num_good, num_bad); if (debugLevel > -4) printStats ("After iteration "+niter, true, num_all, num_undef, num_good, num_bad);
if (debugLevel > -4) { if (debugLevel > -4) {
System.out.println("Non-centered iteration "+niter+" DONE.\n"); System.out.println("Non-centered iteration "+niter+" DONE.\n");
...@@ -8242,7 +8461,7 @@ public class CuasMotion { ...@@ -8242,7 +8461,7 @@ public class CuasMotion {
cuasMotion.tilesX); // int tilesX) { cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_new_scores); // ImagePlus imp) parentCLT.saveImagePlusInModelDirectory(imp_new_scores); // ImagePlus imp)
} }
} } // end of phase 1
//=========================================================================== //===========================================================================
...@@ -8312,6 +8531,10 @@ public class CuasMotion { ...@@ -8312,6 +8531,10 @@ public class CuasMotion {
trimTargets( // limit number of targets per tile trimTargets( // limit number of targets per tile
target_sequence_multi, // final double [][][][] target_multi, target_sequence_multi, // final double [][][][] target_multi,
trim_first); // final int max_targets) { trim_first); // final int max_targets) {
setPhase1Score( // Set Phase 1 target index and score (to fine-tune thresholds to reduce false positives
target_sequence_multi); // final double [][][][] target_multi) {
if (intermed_low) { if (intermed_low) {
ImagePlus imp_new_scores = showTargetSequence( ImagePlus imp_new_scores = showTargetSequence(
target_sequence_multi, // double [][][][] vector_fields_sequence, target_sequence_multi, // double [][][][] vector_fields_sequence,
...@@ -8331,17 +8554,6 @@ public class CuasMotion { ...@@ -8331,17 +8554,6 @@ public class CuasMotion {
} }
int niter_lim = niter+ num_cycles; int niter_lim = niter+ num_cycles;
int iter_show1 = iter_show + niter; int iter_show1 = iter_show + niter;
/*
if (intermed_low && debug_more) {
ImagePlus imp_mv_strength = showTargetSequence(
motion_sequence, // double [][][] vector_fields_sequence,
slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
model_prefix+"-MOTION_SEQUENCE-PRE-CENT",// String title,
!batch_mode, // boolean show,
cuasMotion.tilesX); // int tilesX) {
parentCLT.saveImagePlusInModelDirectory(imp_mv_strength);
}
*/
int niter0 = niter; // for debugging, so (niter - niter0) will start from 0 int niter0 = niter; // for debugging, so (niter - niter0) will start from 0
for (; niter < niter_lim; niter++) { for (; niter < niter_lim; niter++) {
boolean good_only= false; boolean good_only= false;
...@@ -8349,14 +8561,22 @@ public class CuasMotion { ...@@ -8349,14 +8561,22 @@ public class CuasMotion {
boolean save_filtered_low = intermed_low && (niter < iter_show1); boolean save_filtered_low = intermed_low && (niter < iter_show1);
boolean save_filtered_high = intermed_high && (niter < iter_show1); boolean save_filtered_high = intermed_high && (niter < iter_show1);
totals = getRemain(target_sequence_multi, num_all, num_undef, num_good, num_bad); totals = getRemain(
target_sequence_multi, // final double [][][][] target_sequence_multi,
num_all, // int [] num_all_in,
null, // int [] num_motion_undef_in, // if non-null, will use it instead of num_noncentered_in // AF 05/20/2026
// next will be ignored if num_motion_undef_in != null
num_undef, // int [] num_noncentered_in,
num_good, // int [] num_good_in,
num_bad); // int [] num_bad_in)
if (totals[TOTALS_UNDEFINED] == 0) { if (totals[TOTALS_UNDEFINED] == 0) {
if (debugLevel > -4) System.out.println ("No undefined tiles left, breaking loop"); if (debugLevel > -4) System.out.println ("No undefined tiles left, breaking loop");
break; break;
} }
int [][] filter5 = filter5Targets( // will ignore failed tiles int [][] filter5 = filter5Targets( // will ignore failed tiles
null, // motion_sequence, // final double [][][] target_sequence, // null, // motion_sequence, // final double [][][] target_sequence,
target_sequence_multi, // final double [][][][] target_sequence_multi,non-centered marked as "used" target_sequence_multi, // final double [][][][] target_sequence_multi,non-centered marked as "used"
// if use motion and select_new will only consider tiles (and compare motion scores in motion_sequence) that have nulls in target_sequence_multi[nseq][ntile] // if use motion and select_new will only consider tiles (and compare motion scores in motion_sequence) that have nulls in target_sequence_multi[nseq][ntile]
// if not use motion and select_new will only consider (and compare scores) tiles that have [RSLT_CENTERED] = 0.0 // if not use motion and select_new will only consider (and compare scores) tiles that have [RSLT_CENTERED] = 0.0
...@@ -8489,7 +8709,8 @@ public class CuasMotion { ...@@ -8489,7 +8709,8 @@ public class CuasMotion {
parentCLT.saveImagePlusInModelDirectory(imp_ext); parentCLT.saveImagePlusInModelDirectory(imp_ext);
} }
double [][][][] targets_new_multi=getNewCenteredTargets( double [][][][] targets_new_multi=getNewTargets(
true, // boolean centered,
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
cuasMotion, // CuasMotion cuasMotion, cuasMotion, // CuasMotion cuasMotion,
fpixels_accum, // float [][] fpixels_accum, fpixels_accum, // float [][] fpixels_accum,
...@@ -8517,6 +8738,11 @@ public class CuasMotion { ...@@ -8517,6 +8738,11 @@ public class CuasMotion {
filter_below_horizon, // double filter_below_horizon, filter_below_horizon, // double filter_below_horizon,
lmax_hack_ridge, // double lmax_hack_ridge, lmax_hack_ridge, // double lmax_hack_ridge,
lmax_radius, // double lmax_radius, lmax_radius, // double lmax_radius,
lmax_radius, // double centered_radius,
0.5, // double centered_radius_blur,
1.0, // double pix_tolerance, //
target_radius, // double target_radius, target_radius, // double target_radius,
n_recenter, // int n_recenter, n_recenter, // int n_recenter,
no_border, // boolean no_border, no_border, // boolean no_border,
...@@ -8642,7 +8868,8 @@ public class CuasMotion { ...@@ -8642,7 +8868,8 @@ public class CuasMotion {
parentCLT.saveImagePlusInModelDirectory(imp_ext); parentCLT.saveImagePlusInModelDirectory(imp_ext);
} }
double [][][][] targets_new_multi=getNewCenteredTargets( double [][][][] targets_new_multi=getNewTargets(
true, // boolean centered,
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
cuasMotion, // CuasMotion cuasMotion, cuasMotion, // CuasMotion cuasMotion,
fpixels_accum, // float [][] fpixels_accum, fpixels_accum, // float [][] fpixels_accum,
...@@ -8669,6 +8896,11 @@ public class CuasMotion { ...@@ -8669,6 +8896,11 @@ public class CuasMotion {
filter_below_horizon, // double filter_below_horizon, filter_below_horizon, // double filter_below_horizon,
lmax_hack_ridge, // double lmax_hack_ridge, lmax_hack_ridge, // double lmax_hack_ridge,
lmax_radius, // double lmax_radius, lmax_radius, // double lmax_radius,
lmax_radius, // double centered_radius,
0.5, // double centered_radius_blur,
1.0, // double pix_tolerance, //
target_radius, // double target_radius, target_radius, // double target_radius,
n_recenter, // int n_recenter, n_recenter, // int n_recenter,
no_border, // boolean no_border, no_border, // boolean no_border,
...@@ -8750,9 +8982,18 @@ public class CuasMotion { ...@@ -8750,9 +8982,18 @@ public class CuasMotion {
if (debugLevel > -4) System.out.println ("Nothing added from last try, breaking the loop.\n"); if (debugLevel > -4) System.out.println ("Nothing added from last try, breaking the loop.\n");
break; // breaks here break; // breaks here
} }
totals = getRemain(target_sequence_multi, num_all, num_undef, num_good, num_bad); totals = getRemain(
target_sequence_multi, // final double [][][][] target_sequence_multi,
num_all, // int [] num_all_in,
null, // int [] num_motion_undef_in, // if non-null, will use it instead of num_noncentered_in // AF 05/20/2026
// next will be ignored if num_motion_undef_in != null
num_undef, // int [] num_noncentered_in,
num_good, // int [] num_good_in,
num_bad); // int [] num_bad_in)
if (debugLevel > -4) printStats ("After centered iteration "+niter, true, num_all, num_undef, num_good, num_bad); if (debugLevel > -4) printStats ("After centered iteration "+niter, true, num_all, num_undef, num_good, num_bad);
if (debugLevel > -4) { if (debugLevel > -4) {
System.out.print((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+": "));
System.out.println("Centered iteration "+niter+" DONE.\n"); System.out.println("Centered iteration "+niter+" DONE.\n");
} }
} //for (niter=0; niter < max_iter; niter++) } //for (niter=0; niter < max_iter; niter++)
...@@ -8783,7 +9024,8 @@ public class CuasMotion { ...@@ -8783,7 +9024,8 @@ public class CuasMotion {
return target_sequence_multi; // target_sequence; // contains all tiles, good or bad, their data and when they were defined return target_sequence_multi; // target_sequence; // contains all tiles, good or bad, their data and when they were defined
} }
private static double [][][][] getNewCenteredTargets( private static double [][][][] getNewTargets(
boolean centered,
CLTParameters clt_parameters, CLTParameters clt_parameters,
CuasMotion cuasMotion, CuasMotion cuasMotion,
float [][] fpixels_accum, float [][] fpixels_accum,
...@@ -8799,7 +9041,6 @@ public class CuasMotion { ...@@ -8799,7 +9041,6 @@ public class CuasMotion {
String model_prefix, String model_prefix,
int niter, int niter,
double input_range, double input_range,
double lmax_fraction, double lmax_fraction,
double lmax_flt_neglim, double lmax_flt_neglim,
double lmax_flt_hsigma, double lmax_flt_hsigma,
...@@ -8810,6 +9051,11 @@ public class CuasMotion { ...@@ -8810,6 +9051,11 @@ public class CuasMotion {
double filter_below_horizon, double filter_below_horizon,
double lmax_hack_ridge, double lmax_hack_ridge,
double lmax_radius, double lmax_radius,
double centered_radius,
double centered_radius_blur,
double duplicate_tolerance, //
double target_radius, // final double centroid_radius, double target_radius, // final double centroid_radius,
int n_recenter, // final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass) int n_recenter, // final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass)
boolean no_border, boolean no_border,
...@@ -8862,7 +9108,7 @@ public class CuasMotion { ...@@ -8862,7 +9108,7 @@ public class CuasMotion {
// perform new accumulations of shifted non-conflicting tiles // perform new accumulations of shifted non-conflicting tiles
float [][] fpixels_accumulated = cuasMotion.shiftAndRenderAccumulate( float [][] fpixels_accumulated = cuasMotion.shiftAndRenderAccumulate(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
true, // false, // final boolean center, // why is it false here? centered, // false, // final boolean center, // why is it false here?
false, // final boolean fill_zeros, false, // final boolean fill_zeros,
fpixels_accum, // By Claude on 05/07/2026: LPF'd with accum_ra (was fpixels_tum) fpixels_accum, // By Claude on 05/07/2026: LPF'd with accum_ra (was fpixels_tum)
extended_scan, // final double [][][] vector_field, extended_scan, // final double [][][] vector_field,
...@@ -8874,7 +9120,7 @@ public class CuasMotion { ...@@ -8874,7 +9120,7 @@ public class CuasMotion {
corr_offset, // final int corr_offset, // interframe distance for correlation corr_offset, // final int corr_offset, // interframe distance for correlation
true); // final boolean batch_mode) { true); // final boolean batch_mode) {
if (save_filtered_high) { if (save_filtered_high) {
String title = model_prefix+"-ACCUMULATED-CENTERED-n"+niter; String title = model_prefix+"-ACCUMULATED"+(centered?"-CENTERED":"")+"-n"+niter;
if (boost_accum_pairs > 1.0) { if (boost_accum_pairs > 1.0) {
title+="-BOOST"+boost_accum_pairs; title+="-BOOST"+boost_accum_pairs;
} }
...@@ -8893,7 +9139,7 @@ public class CuasMotion { ...@@ -8893,7 +9139,7 @@ public class CuasMotion {
// replace center frames with the accumulated ones // replace center frames with the accumulated ones
if (debugLevel > -4) { if (debugLevel > -4) {
System.out.println("Starting render, iteration = "+niter); System.out.println("Starting render,"+(centered?"centered ":"")+" iteration = "+niter);
} }
// show just fpixels_accumulated // show just fpixels_accumulated
...@@ -8907,7 +9153,7 @@ public class CuasMotion { ...@@ -8907,7 +9153,7 @@ public class CuasMotion {
double [][][][] targets_new_multi = getAccumulatedCoordinatesMulti( double [][][][] targets_new_multi = getAccumulatedCoordinatesMulti(
keep_failed, // final boolean keep_failed, // keep failed targets keep_failed, // final boolean keep_failed, // keep failed targets
niter, // final int when, // set if >=0 for failures niter, // final int when, // set if >=0 for failures
true, // final boolean centered, centered, // final boolean centered,
boost_accum_pairs, // final double boost_exposure, boost_accum_pairs, // final double boost_exposure,
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
...@@ -8921,9 +9167,9 @@ public class CuasMotion { ...@@ -8921,9 +9167,9 @@ public class CuasMotion {
target_horizon+filter_below_horizon, // final double lma_horizon, target_horizon+filter_below_horizon, // final double lma_horizon,
lmax_hack_ridge, // final double lmax_hack_ridge, // 0.45; // Hack for ridges: remove horizontal streaks, where average(abs()) for the line exceeds fraction of abs max 0.32-good, 0.55 - bad lmax_hack_ridge, // final double lmax_hack_ridge, // 0.45; // Hack for ridges: remove horizontal streaks, where average(abs()) for the line exceeds fraction of abs max 0.32-good, 0.55 - bad
lmax_radius, // final int cuas_lmax_radius, // 3; // look inside cuas_lmax_radius* 2 + 1 square for the local maximum isolation lmax_radius, // final int cuas_lmax_radius, // 3; // look inside cuas_lmax_radius* 2 + 1 square for the local maximum isolation
lmax_radius, // final double centered_radius, centered_radius, //lmax_radius, // final double centered_radius,
0.5, // final double centered_radius_blur, centered_radius_blur, // 0.5, // final double centered_radius_blur,
1.0, // final double pix_tolerance, // duplicate_tolerance, // 1.0, // final double pix_tolerance, //
// lmax_zero, // final boolean cuas_lmax_zero, // true; // zero all data outside this radius from the maximum // lmax_zero, // final boolean cuas_lmax_zero, // true; // zero all data outside this radius from the maximum
target_radius, // final double centroid_radius, target_radius, // final double centroid_radius,
n_recenter, // final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass) n_recenter, // final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass)
...@@ -8946,14 +9192,14 @@ public class CuasMotion { ...@@ -8946,14 +9192,14 @@ public class CuasMotion {
lambda_max, // final double lambda_max, lambda_max, // final double lambda_max,
rms_diff, // final double rms_diff, rms_diff, // final double rms_diff,
num_iter, // final int num_iter,0, // final double pre_min_a, // pre-filter minimal LMA-A (half finbal?) num_iter, // final int num_iter,0, // final double pre_min_a, // pre-filter minimal LMA-A (half finbal?)
lma_pre_mina*lma_mina,// final double pre_min_a, // 0.5 //scale cuas_lma_mina to filter initial candidates (if there are > one of them) lma_pre_mina*lma_mina,// final double pre_min_a, // 0.5 //scale cuas_lma_mina to filter initial candidates (if there are > one of them)
min_keep, // final int min_keep, // 2; // keep at least this number of candidates before using cuas_lma_pre_mina filter min_keep, // final int min_keep, // 2; // keep at least this number of candidates before using cuas_lma_pre_mina filter
accum_debug, // final float [][] accum_debug, accum_debug, // final float [][] accum_debug,
cuasMotion.parentCLT, // final QuadCLT parentCLT, // debug only, maybe null in other cases cuasMotion.parentCLT, // final QuadCLT parentCLT, // debug only, maybe null in other cases
debugLevel); // final int debugLevel); debugLevel); // final int debugLevel);
if (accum_debug != null) { if (accum_debug != null) {
String title = model_prefix+"-ACCUMULATED_FILTERED-CENTERED-MULTI-n"+niter; String title = model_prefix+"-ACCUMULATED_FILTERED"+(centered?"-CENTERED":"")+"-n"+niter;
if (boost_accum_pairs > 1.0) { if (boost_accum_pairs > 1.0) {
title+="-BOOST"+boost_accum_pairs; title+="-BOOST"+boost_accum_pairs;
} }
...@@ -8978,11 +9224,10 @@ public class CuasMotion { ...@@ -8978,11 +9224,10 @@ public class CuasMotion {
if (save_filtered_low && debug_more) { if (save_filtered_low && debug_more) {
String title = model_prefix+"-NEW-TARGETS-CENTERED-MULTI-n"+niter; String title = model_prefix+"-NEW-TARGETS"+(centered?"-CENTERED":"")+"-n"+niter;
if (boost_accum_pairs > 1.0) { if (boost_accum_pairs > 1.0) {
title+="-BOOST"+boost_accum_pairs; title+="-BOOST"+boost_accum_pairs;
} }
ImagePlus imp_new = showTargetSequence( ImagePlus imp_new = showTargetSequence(
targets_new_multi, // final double [][][][] targets_multi, targets_new_multi, // final double [][][][] targets_multi,
cuasMotion.slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null cuasMotion.slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
...@@ -9013,11 +9258,9 @@ public class CuasMotion { ...@@ -9013,11 +9258,9 @@ public class CuasMotion {
fail_mismatch, // final boolean fail_mismatch, fail_mismatch, // final boolean fail_mismatch,
offcenter, // final double offcenter, offcenter, // final double offcenter,
cuasMotion.getNoiseNeibs(), // final int [] noise_neibs, cuasMotion.getNoiseNeibs(), // final int [] noise_neibs,
// cuasMotion.getNoiseMap(), // final double [] noise_map,
// noisemax, // final double noise_max,
target_horizon, // final double lma_horizon, // horizon as maximal pixel Y target_horizon, // final double lma_horizon, // horizon as maximal pixel Y
cuasMotion.tilesX); // final int tilesX, cuasMotion.tilesX); // final int tilesX,
int [] remain_es_centered = getScore( getScore(
targets_new_multi, // final double [][][] target_sequence, // modifies certain fields (scores) targets_new_multi, // final double [][][] target_sequence, // modifies certain fields (scores)
factor_lim, // final double importance_limit, factor_lim, // final double importance_limit,
factor_pow, // final double importance_power, // Raise each factor to this power before combining factor_pow, // final double importance_power, // Raise each factor to this power before combining
...@@ -9025,7 +9268,7 @@ public class CuasMotion { ...@@ -9025,7 +9268,7 @@ public class CuasMotion {
slow_score, // final double slow_score, // multiply total score for targets detected in slow target mode slow_score, // final double slow_score, // multiply total score for targets detected in slow target mode
cuasMotion.tilesX); // final int tilesX, cuasMotion.tilesX); // final int tilesX,
if (save_filtered_low) { if (save_filtered_low) {
String title = model_prefix+"-NEW-TARGETS_CENTERED_SCORES_MULTI-n"+niter; String title = model_prefix+"-NEW-TARGETS"+(centered?"_CENTERED":"")+"_SCORES_MULTI-n"+niter;
if (boost_accum_pairs > 1.0) { if (boost_accum_pairs > 1.0) {
title+="-BOOST"+boost_accum_pairs; title+="-BOOST"+boost_accum_pairs;
} }
...@@ -9058,6 +9301,8 @@ public class CuasMotion { ...@@ -9058,6 +9301,8 @@ public class CuasMotion {
* @param debugLevel * @param debugLevel
* @return * @return
*/ */
/*
@Deprecated
public static int [][] filter5Targets( // should work for motion vectors and target coordinates returns index of selected target or -1 for unselected public static int [][] filter5Targets( // should work for motion vectors and target coordinates returns index of selected target or -1 for unselected
final double [][][] motion_sequence, // may be null final double [][][] motion_sequence, // may be null
final double [][][][] target_sequence_multi, // not null final double [][][][] target_sequence_multi, // not null
...@@ -9397,6 +9642,371 @@ public class CuasMotion { ...@@ -9397,6 +9642,371 @@ public class CuasMotion {
} }
return filter5; return filter5;
} }
*/
// removing final double [][][] motion_sequence, // AF 05/22/2026
public static int [][] filter5Targets( // should work for motion vectors and target coordinates returns index of selected target or -1 for unselected
final double [][][][] target_sequence_multi, // not null
// if use motion and select_new will only consider tiles (and compare motion scores in motion_sequence) that have nulls in target_sequence_multi[nseq][ntile]
// if not use motion and select_new will only consider (and compare scores) tiles that have [RSLT_CENTERED] = 0.0. After selection will mark those as
// if not select_new (assumes not use motion) will return best (and good) target indices
final boolean use_motion_in, // true - use motion vectors confidence, false - use target confidence
final boolean select_new_in, // true - use only untested tiles, false - use good tiles
// when using good ones - will select first good one (best if correctly ordered)
final double min_confidence, // 0 OK
final double lma_horizon, // target below horizon
final int tilesX,
final int range, // 1 or 2
final int [] remain,
final int [] passes, // debugging - number of passes required
final int debugLevel){
final boolean use_motion = use_motion_in; // By Claude on 05/07/2026: decouple from motion_sequence presence
final boolean select_new = select_new_in; // By Claude on 05/07/2026: decouple from motion_sequence
boolean debug_now = (debugLevel<5);
final int num_seq = target_sequence_multi.length;
final int num_tiles = target_sequence_multi[0].length;
final int tilesY = num_tiles/ tilesX;
final int [][] filter5 = new int [num_seq][num_tiles];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final int dbg_tile = debug_now ?(55+38*80) : -1;
final int dbg_seq0 = debug_now ? 166:-1; //27: -1;
final int dbg_seq1 = debug_now ? 166:-1; // 29: -1;
final int ihorizon = (lma_horizon > 0) ?( (int) Math.ceil(lma_horizon/GPUTileProcessor.DTT_SIZE)) : -1; // tiles with tileY >= ihorizon are removed
if (dbg_tile >=0) {
System.out.println("filter5Targets()):00: use_motion="+use_motion+", select_new="+select_new+", ihorizon="+ihorizon);
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
TileNeibs tn = new TileNeibs(tilesX, tilesY);
boolean [] prohibit = new boolean [num_tiles];
for (int nSeq = ai.getAndIncrement(); nSeq < num_seq; nSeq = ai.getAndIncrement()) {
Arrays.fill(filter5[nSeq], -1);
int num_total = 0;
Arrays.fill(prohibit, false);
// set initially prohibited tiles - ones not to consider when competing
for (int ntile = 0; ntile < num_tiles; ntile++) {
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):0: ntile="+ntile+", nSeq="+nSeq);
}
if (select_new){
if (use_motion ) { // Get motion from target 0 - it has only motion vectors
// should have a single target containing vlaid (not to weak) motion vector.
// now weak have failure already set, so ignore only failed or used
// use only target[0] here, others are added
double [][] targets = target_sequence_multi[nSeq][ntile];
prohibit[ntile] = (targets == null) ||
(targets.length != 1) ||
(!Double.isNaN(targets[0][CuasMotionLMA.RSLT_FAIL]) && //
(targets[0][CuasMotionLMA.RSLT_FAIL]!= CuasMotionLMA.FAIL_NONE));
} else { // !use_motion - find if it has at least one good with that have [RSLT_CENTERED] = 0.0
boolean prohibit_this = true;
double [][] targets = target_sequence_multi[nSeq][ntile];
if (targets != null) {
for (int i = 0; i < targets.length; i++) if (targets[i] != null) {
if ((targets[i][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_NONE) &&
(targets[i][CuasMotionLMA.RSLT_CENTERED] == CuasMotionLMA.CENTERED_NO)) {
prohibit_this = false; // still have some potential targets that were not tried in centered mode
}
}
}
prohibit[ntile] |= prohibit_this;
}
} else { // valid motion (or motion_sequence==null), not select new - prohibit if no good targets for this tile
boolean prohibit_this = true;
double [][] targets = target_sequence_multi[nSeq][ntile];
if (targets != null) {
for (int i = 0; i < targets.length; i++) if (targets[i] != null){
if ((targets[i][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_NONE) &&
(targets[i][CuasMotionLMA.RSLT_CENTERED] != CuasMotionLMA.CENTERED_USED)) {
prohibit_this = false; // still have some potential targets that were not tried in centered mode
break;
}
}
}
prohibit[ntile] |= prohibit_this;
}
}
// is it still used?
if ((ihorizon > 0) && (ihorizon < tilesY)) {
Arrays.fill(prohibit, ihorizon*tilesX, num_tiles, true);
}
if ((nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):2: nSeq="+nSeq);
}
int num_this_pass = 0;
int npass = 0;
do {
npass++;
num_this_pass = 0; // number of new tiles added at this pass
for (int tileY = 0; tileY < tilesY; tileY++) {
for (int tileX = 0; tileX < tilesX; tileX++) {
int ntile = tileX + tilesX * tileY;
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):1: ntile="+ntile+", nSeq="+nSeq+", npass="+npass+
", num_this_pass="+num_this_pass+", num_total="+num_total+" prohibit["+ntile+"]="+prohibit[ntile]);
}
if (!prohibit[ntile]) { // targets[ntile][conf_index] >0 here by the prohibit preset
boolean ismax = true;
if (select_new) {
double [][] targets = target_sequence_multi[nSeq][ntile];
if (use_motion) {
check_max_motion:{
double cval = targets[0][CuasMotionLMA.RSLT_MSCORE] - min_confidence;
// double cval = motion[ntile][CuasMotionLMA.RSLT_MSCORE] - min_confidence;
// should be already >= 0, filtered once before iterations
if (cval <= 0) {
ismax = false;
prohibit[ntile] = true; // not needed
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):10: ntile="+ntile+", nSeq="+nSeq+", npass="+npass+
", num_this_pass="+num_this_pass+", num_total="+num_total+" prohibit["+ntile+"]="+prohibit[ntile]);
}
break check_max_motion;
}
for (int dy = -range; dy <= range; dy++) {
for (int dx = -range; dx <= range; dx++) {
int indx = tn.getNeibIndex(ntile, dx, dy);
if ((indx >= 0) && !prohibit[indx]) {
// double val = motion[indx][CuasMotionLMA.RSLT_MSCORE]- min_confidence;
double val = target_sequence_multi[nSeq][indx][0][CuasMotionLMA.RSLT_MSCORE]- min_confidence;
if (val > cval) {
ismax = false;
break check_max_motion;
}
}
}
}
filter5[nSeq][ntile] = 0;
// Also mark used
target_sequence_multi[nSeq][ntile][0][CuasMotionLMA.RSLT_CENTERED] = CuasMotionLMA.CENTERED_USED;
}
/*
// By Claude on 05/07/2026: motion==null, rank FAIL_PENDING+CENTERED_NO sentinels by QSCORE
double [][] targets = target_sequence_multi[nSeq][ntile];
if (targets != null) {
int best_pending = -1;
check_max_pending:{
for (int ntarg = 0; ntarg < targets.length; ntarg++) if (targets[ntarg] != null &&
targets[ntarg][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_PENDING &&
targets[ntarg][CuasMotionLMA.RSLT_CENTERED] == CuasMotionLMA.CENTERED_NO) {
double qval = targets[ntarg][CuasMotionLMA.RSLT_QSCORE];
if ((best_pending < 0) || (qval > targets[best_pending][CuasMotionLMA.RSLT_QSCORE])) {
best_pending = ntarg;
}
}
if (best_pending < 0) {
ismax = false;
prohibit[ntile] = true;
break check_max_pending;
}
double cval = targets[best_pending][CuasMotionLMA.RSLT_QSCORE] - min_confidence;
if (cval <= 0) {
ismax = false;
prohibit[ntile] = true;
break check_max_pending;
}
for (int dy = -range; dy <= range; dy++) {
for (int dx = -range; dx <= range; dx++) {
int ntile1 = tn.getNeibIndex(ntile, dx, dy);
if ((ntile1 >= 0) && !prohibit[ntile1]) {
double [][] other_targets = target_sequence_multi[nSeq][ntile1];
if (other_targets != null) {
for (int ntarg = 0; ntarg < other_targets.length; ntarg++) if (other_targets[ntarg] != null &&
other_targets[ntarg][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_PENDING &&
other_targets[ntarg][CuasMotionLMA.RSLT_CENTERED] == CuasMotionLMA.CENTERED_NO) {
double val = other_targets[ntarg][CuasMotionLMA.RSLT_QSCORE];
if (val > cval + min_confidence) {
ismax = false;
break check_max_pending;
}
}
}
}
}
}
filter5[nSeq][ntile] = best_pending;
} // check_max_pending
} else {
prohibit[ntile] = true;
}
*/
} else { // not using motion, only consider non-centered good tiles
// double [][] targets = target_sequence_multi[nSeq][ntile];
if (targets != null) {
// find the best non-centered good target in this tile
int best_targ = -1;
check_max_target:{
for (int ntarg = 0; ntarg < targets.length; ntarg++) if ((targets[ntarg] != null) &&
(targets[ntarg][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_NONE) &&
(targets[ntarg][CuasMotionLMA.RSLT_CENTERED] == CuasMotionLMA.CENTERED_NO)) {
double cval = targets[ntarg][CuasMotionLMA.RSLT_QSCORE];
if ((cval > 0) && ((best_targ <0) || (cval > targets[best_targ][CuasMotionLMA.RSLT_QSCORE]))) {
best_targ = ntarg;
}
}
if (best_targ < 0) {
ismax = false;
prohibit[ntile] = true; // not needed
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):11: ntile="+ntile+", nSeq="+nSeq+", npass="+npass+
", num_this_pass="+num_this_pass+", num_total="+num_total+" prohibit["+ntile+"]="+prohibit[ntile]);
}
break check_max_target;
}
double cval = targets[best_targ][CuasMotionLMA.RSLT_QSCORE];
for (int dy = -range; dy <= range; dy++) {
for (int dx = -range; dx <= range; dx++) {
int ntile1 = tn.getNeibIndex(ntile, dx, dy);
if ((ntile1 >= 0) && !prohibit[ntile1]) {
// targets = target_sequence_multi[nSeq][ntile]; // other targets
double [][] other_targets = target_sequence_multi[nSeq][ntile1]; // other targets
if (other_targets != null) {
for (int ntarg = 0; ntarg < other_targets.length; ntarg++) if ((other_targets[ntarg] != null) &&
(other_targets[ntarg][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_NONE) &&
(other_targets[ntarg][CuasMotionLMA.RSLT_CENTERED] == CuasMotionLMA.CENTERED_NO)) {
double val = other_targets[ntarg][CuasMotionLMA.RSLT_QSCORE];
if (val > cval) {
ismax = false;
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):12: ntile="+ntile+", nSeq="+nSeq+", npass="+npass+
", num_this_pass="+num_this_pass+", num_total="+num_total+" prohibit["+ntile+"]="+prohibit[ntile]);
}
break check_max_target;
}
}
}
}
}
}
filter5[nSeq][ntile] = best_targ;
} // check_max_target:{
} else {
prohibit[ntile] = true; // probably not needed
}
}
} else {//if (select_new) find best good target (assuming non-motion)
double [][] targets = target_sequence_multi[nSeq][ntile];
if (targets != null) {
// find the best good target in this tile ?
int best_targ = -1;
check_max_target_any:{
for (int ntarg = 0; ntarg < targets.length; ntarg++) if ((targets[ntarg] != null) &&
(targets[ntarg][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_NONE) &&
(targets[ntarg][CuasMotionLMA.RSLT_CENTERED] != CuasMotionLMA.CENTERED_USED)) {
double cval = targets[ntarg][CuasMotionLMA.RSLT_QSCORE];
if ((cval > 0) && ((best_targ <0) || (cval > targets[best_targ][CuasMotionLMA.RSLT_QSCORE]))) {
best_targ = ntarg;
}
}
if (best_targ < 0) {
ismax = false;
prohibit[ntile] = true; // not needed
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):13: ntile="+ntile+", nSeq="+nSeq+", npass="+npass+
", num_this_pass="+num_this_pass+", num_total="+num_total+" prohibit["+ntile+"]="+prohibit[ntile]);
}
break check_max_target_any;
}
double cval = targets[best_targ][CuasMotionLMA.RSLT_QSCORE];
for (int dy = -range; dy <= range; dy++) {
for (int dx = -range; dx <= range; dx++) {
int ntile1 = tn.getNeibIndex(ntile, dx, dy);
if ((ntile1 >= 0) && !prohibit[ntile1]) {
// targets = target_sequence_multi[nSeq][ntile1]; // other targets
double [][] other_targets = target_sequence_multi[nSeq][ntile1]; // other targets
if (other_targets != null) {
for (int ntarg = 0; ntarg < other_targets.length; ntarg++) if ((other_targets[ntarg] != null) &&
(other_targets[ntarg][CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_NONE) &&
(other_targets[ntarg][CuasMotionLMA.RSLT_CENTERED] != CuasMotionLMA.CENTERED_USED)) {
double val = other_targets[ntarg][CuasMotionLMA.RSLT_QSCORE];
if (val > cval) {
ismax = false;
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):14: ntile="+ntile+", nSeq="+nSeq+", npass="+npass+
", num_this_pass="+num_this_pass+", num_total="+num_total+" prohibit["+ntile+"]="+prohibit[ntile]);
}
break check_max_target_any;
}
}
}
}
}
}
filter5[nSeq][ntile] = best_targ;
} // check_max_target_any
}
} //if (select_new) else
if (ismax) {
// filter5[nSeq][ntile] = true; // ismax; already set
// prohibit all around, including this one
for (int dy = -range; dy <= range; dy++) {
for (int dx = -range; dx <= range; dx++) {
int indx = tn.getNeibIndex(ntile, dx, dy);
if (indx >= 0) { // && ((filtered == null) || !filtered[nSeq][indx])){
prohibit[indx] = true;
if ((indx == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):15: indx="+indx+", ntile="+ntile+", nSeq="+nSeq+", npass="+npass+
", num_this_pass="+num_this_pass+", num_total="+num_total+" prohibit["+ntile+"]="+prohibit[ntile]);
}
}
}
}
num_this_pass++;
}
} // if (!prohibit[ntile]) { // targets[ntile][conf_index] >0 here by the prohibit preset
} // for (int tileX = 0; tileX < tilesX; tileX++)
} // for (int tileY = 0; tileY < tilesY; tileY++) {
num_total+=num_this_pass;
} while (num_this_pass > 0);
if (remain != null) {
remain[nSeq] = num_total;
}
if (passes != null) {
passes[nSeq] = npass;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// By Claude on 05/07/2026: also mark FAIL_PENDING sentinels when use_motion=true, motion==null
if (select_new && !use_motion) { // && (!use_motion || (motion_sequence == null))) {
ai.set(0);
// mark selected targets as "used" (CENTERED_USED): FAIL_NONE+CENTERED_NO or FAIL_PENDING+CENTERED_NO
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSeq = ai.getAndIncrement(); nSeq < num_seq; nSeq = ai.getAndIncrement()) {
for (int ntile = 0; ntile < num_tiles; ntile++) { // if (target_sequence[nSeq][ntile] != null) {
if ((ntile == dbg_tile)&& (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("filter5Targets()):4: filter5["+nSeq+"]["+ntile+"]="+filter5[nSeq][ntile]);
}
if (filter5[nSeq][ntile] >= 0) {
target_sequence_multi[nSeq][ntile][filter5[nSeq][ntile]][CuasMotionLMA.RSLT_CENTERED] = CuasMotionLMA.CENTERED_USED;
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("16.target_sequence_multi["+nSeq+"]["+ntile+"]["+filter5[nSeq][ntile]+"]["+CuasMotionLMA.RSLT_CENTERED+"] ="+
target_sequence_multi[nSeq][ntile][filter5[nSeq][ntile]][CuasMotionLMA.RSLT_CENTERED]);
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
return filter5;
}
// mark all "used" targets (non-centered, after all centered are added) as failed // mark all "used" targets (non-centered, after all centered are added) as failed
public static void failUsed( public static void failUsed(
...@@ -9843,28 +10453,27 @@ public class CuasMotion { ...@@ -9843,28 +10453,27 @@ public class CuasMotion {
return targets_combo; return targets_combo;
} }
public static int [] getRemain( public static int [] getRemain(
final double [][][][] target_sequence_multi, final double [][][][] target_sequence_multi,
int [] num_all_in, int [] num_all_in,
int [] num_motion_undef_in, // if non-null, will use it instead of num_noncentered_in // AF 05/20/2026
// next will be ignored if num_motion_undef_in != null
int [] num_noncentered_in, int [] num_noncentered_in,
int [] num_good_in, int [] num_good_in,
int [] num_bad_in) { int [] num_bad_in) {
final int num_seq = target_sequence_multi.length; final int num_seq = target_sequence_multi.length;
final int num_tiles = target_sequence_multi[0].length; final int num_tiles = target_sequence_multi[0].length;
final int [] num_all = (num_all_in != null) ? num_all_in : new int [num_seq]; final boolean motion_mode = num_motion_undef_in != null;
final int [] num_good = (num_good_in != null) ? num_good_in : new int [num_seq]; final int [] num_all = (num_all_in != null) ? num_all_in : new int [num_seq];
final int [] num_bad = (num_bad_in != null) ? num_bad_in : new int [num_seq]; final int [] num_motion_undef = motion_mode ? num_motion_undef_in : new int [num_seq];
final int [] num_noncentered = (num_noncentered_in != null) ? num_noncentered_in : new int [num_seq]; final int [] num_good = (num_good_in != null) ? num_good_in : new int [num_seq];
Arrays.fill(num_all, 0); // tiles that have good, bad or undefined targets final int [] num_bad = (num_bad_in != null) ? num_bad_in : new int [num_seq];
Arrays.fill(num_good, 0); // good centered targets (may be multiple per tile) final int [] num_noncentered = (num_noncentered_in != null) ? num_noncentered_in : new int [num_seq];
Arrays.fill(num_bad, 0); // bad centered targets (may be multiple per tile) Arrays.fill(num_all, 0); // tiles that have good, bad or undefined targets
Arrays.fill(num_noncentered, 0); // not centered (and not yet used for centering) targets Arrays.fill(num_motion_undef, 0); // tiles, not yet tested from motion
Arrays.fill(num_good, 0); // good centered targets (may be multiple per tile)
Arrays.fill(num_bad, 0); // bad centered targets (may be multiple per tile)
Arrays.fill(num_noncentered, 0); // not centered (and not yet used for centering) targets
final Thread[] threads = ImageDtt.newThreadArray(); final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
...@@ -9879,13 +10488,15 @@ public class CuasMotion { ...@@ -9879,13 +10488,15 @@ public class CuasMotion {
double ts_fail = tsm[ntarg][CuasMotionLMA.RSLT_FAIL]; double ts_fail = tsm[ntarg][CuasMotionLMA.RSLT_FAIL];
int centered = (int) tsm[ntarg][CuasMotionLMA.RSLT_CENTERED]; int centered = (int) tsm[ntarg][CuasMotionLMA.RSLT_CENTERED];
if (centered != CuasMotionLMA.CENTERED_USED) { if (centered != CuasMotionLMA.CENTERED_USED) {
if (ts_fail == CuasMotionLMA.FAIL_PENDING) { // By Claude on 05/07/2026: unprocessed sentinel if (Double.isNaN(tsm[ntarg][CuasMotionLMA.RSLT_CENTERED]) && Double.isNaN(ts_fail)){ // happens only in motion mode
num_noncentered[nSeq]++; num_motion_undef[nSeq]++;
} else if ((centered == CuasMotionLMA.CENTERED_NO) && (ts_fail == CuasMotionLMA.FAIL_NONE)) { // in non-motion mode non-centered good are "undefined", in motion - just good/bad
} else if (!motion_mode && (centered == CuasMotionLMA.CENTERED_NO) && (ts_fail == CuasMotionLMA.FAIL_NONE)) { // only count good uncentered as undefined
num_noncentered[nSeq]++; num_noncentered[nSeq]++;
} else if (ts_fail == CuasMotionLMA.FAIL_NONE) { } else if (ts_fail == CuasMotionLMA.FAIL_NONE) {
num_good[nSeq]++; num_good[nSeq]++;
} else { // both [RSLT_FAIL] is NaN and [RSLT_CENTERED] is NaN - MV-only
} else{ //
num_bad[nSeq]++; num_bad[nSeq]++;
} }
} }
...@@ -9898,10 +10509,10 @@ public class CuasMotion { ...@@ -9898,10 +10509,10 @@ public class CuasMotion {
} }
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
return getTotals( return getTotals(
num_all, // int [] num_all, num_all, // int [] num_all,
num_noncentered, // int [] num_undef, (num_motion_undef_in != null) ? num_motion_undef: num_noncentered, // int [] num_undef,
num_good, // int [] num_good, num_good, // int [] num_good,
num_bad); // int [] num_bad) num_bad); // int [] num_bad)
} }
...@@ -10122,8 +10733,15 @@ public class CuasMotion { ...@@ -10122,8 +10733,15 @@ public class CuasMotion {
score_coeff, // final double [] importance, // for now (each - squared?): [0] - Amplitude (A/A0), 1 - RMS (RMS0/RMS), 2 - RRMS((RMS/A0) / (RMS/A) score_coeff, // final double [] importance, // for now (each - squared?): [0] - Amplitude (A/A0), 1 - RMS (RMS0/RMS), 2 - RRMS((RMS/A0) / (RMS/A)
slow_score, // final double slow_score, // multiply total score for targets detected in slow target mode slow_score, // final double slow_score, // multiply total score for targets detected in slow target mode
cuasMotion.tilesX); // final int tilesX, cuasMotion.tilesX); // final int tilesX,
getRemain(
getRemain(targets_multi, num_all, num_undef, num_good, num_bad); targets_multi, // final double [][][][] target_sequence_multi,
num_all, // int [] num_all_in,
null, // int [] num_motion_undef_in, // if non-null, will use it instead of num_noncentered_in // AF 05/20/2026
// next will be ignored if num_motion_undef_in != null
num_undef, // int [] num_noncentered_in,
num_good, // int [] num_good_in,
num_bad); // int [] num_bad_in)
if (debugLevel > -4) printStats ("Resolving, after matching before/after", true,num_all, num_undef, num_good, num_bad); if (debugLevel > -4) printStats ("Resolving, after matching before/after", true,num_all, num_undef, num_good, num_bad);
if (intermed_low && debug_more) { if (intermed_low && debug_more) {
ImagePlus imp_failures = showTargetSequence( ImagePlus imp_failures = showTargetSequence(
...@@ -10140,7 +10758,7 @@ public class CuasMotion { ...@@ -10140,7 +10758,7 @@ public class CuasMotion {
// no extra recalculations here as was in pre-Multi? // no extra recalculations here as was in pre-Multi?
// Use here the real threshold to remove weak // Use here the real threshold to remove weak
int [][] filter5 = filter5Targets( // will ignore failed tiles int [][] filter5 = filter5Targets( // will ignore failed tiles
null, // final double [][][] target_sequence, // null, // final double [][][] target_sequence,
targets_multi, // final double [][][][] target_sequence_multi, targets_multi, // final double [][][][] target_sequence_multi,
// if use motion and select_new will only consider tiles (and compare motion scores in motion_sequence) that have nulls in target_sequence_multi[nseq][ntile] // if use motion and select_new will only consider tiles (and compare motion scores in motion_sequence) that have nulls in target_sequence_multi[nseq][ntile]
// if not use motion and select_new will only consider (and compare scores) tiles that have [RSLT_CENTERED] = 0.0 // if not use motion and select_new will only consider (and compare scores) tiles that have [RSLT_CENTERED] = 0.0
...@@ -10442,6 +11060,8 @@ public class CuasMotion { ...@@ -10442,6 +11060,8 @@ public class CuasMotion {
targets_good_multi, // double [][][][] targets_good_multi, // all targets, including conflicting targets_good_multi, // double [][][][] targets_good_multi, // all targets, including conflicting
debugLevel); // final int debugLevel) debugLevel); // final int debugLevel)
} }
setTargets(targets_nonconflict); setTargets(targets_nonconflict);
return; return;
......
...@@ -127,8 +127,13 @@ public class CuasMotionLMA { ...@@ -127,8 +127,13 @@ public class CuasMotionLMA {
public static final int RSLT_VEL_AWAY = 63; // axial velocity (positive - away), range derivative (m/s), calculated from the difference to the previous/next series range public static final int RSLT_VEL_AWAY = 63; // axial velocity (positive - away), range derivative (m/s), calculated from the difference to the previous/next series range
public static final int RSLT_VEL_RIGHT = 64; // lateral velocity, right ( calculated from angular and RSLT_GRANGE public static final int RSLT_VEL_RIGHT = 64; // lateral velocity, right ( calculated from angular and RSLT_GRANGE
public static final int RSLT_VEL_UP = 65; // lateral velocity, up ( calculated from angular and RSLT_GRANGE public static final int RSLT_VEL_UP = 65; // lateral velocity, up ( calculated from angular and RSLT_GRANGE
public static final int RSLT_RANGE_LIN = 66; // range linear interpolated using previous/next series if the same target is present there public static final int RSLT_RANGE_LIN = 66; // range linear interpolated using previous/next series if the same target is present there
public static final int RSLT_LEN = RSLT_RANGE_LIN + 1; public static final int RSLT_PHASE1_INDEX = 67; // target index in phase 1 (to trim) - debug feature
public static final int RSLT_PHASE1_SCORE = 68; // target index in phase 1 (to set minimal score for phase 1) - debug feature
public static final int RSLT_PHASE1_AMP = 69; // target index in phase 1 (to set minimal score for phase 1) - debug feature
public static final int RSLT_PHASE1_MSCORE = 70; // target index in phase 1 (to set minimal score for phase 1) - debug feature
public static final int RSLT_PHASE1_VSTR = 71; // target index in phase 1 (to set minimal score for phase 1) - debug feature
public static final int RSLT_LEN = RSLT_PHASE1_VSTR + 1;
public static final String [] LMA_TITLES = public static final String [] LMA_TITLES =
{"X-OFFS","Y-OFFS", "AMPLITUDE", "RADIUS","RAD_POS", "OVERSHOOT","OFFSET","RMSE","RMSE/A","MAX2A","ITERATIONS", {"X-OFFS","Y-OFFS", "AMPLITUDE", "RADIUS","RAD_POS", "OVERSHOOT","OFFSET","RMSE","RMSE/A","MAX2A","ITERATIONS",
...@@ -147,7 +152,8 @@ public class CuasMotionLMA { ...@@ -147,7 +152,8 @@ public class CuasMotionLMA {
"Disparity","Disparity-Diff","Strength","Range","Global-index", "Disparity","Disparity-Diff","Strength","Range","Global-index",
"segment-length","segment-disparity","segment_disp-diff", "segment-strength", "segment-range", "segment-length","segment-disparity","segment_disp-diff", "segment-strength", "segment-range",
"FLOG-px","FLOG-pY","FLOG-DISP","FLOG-range","infinity", "FLOG-px","FLOG-pY","FLOG-DISP","FLOG-range","infinity",
"GTarget-ID","Vel-away", "Vel-right", "Vel-up","Range-linear"}; "GTarget-ID","Vel-away", "Vel-right", "Vel-up","Range-linear",
"Phase1-index","Phase1-score","Phase1-amplitude","Phase1-mscore","Phase1-vstr"};
public static final String EXTRA_SLICE_DISCARD_ON_LOAD = "Targets"; public static final String EXTRA_SLICE_DISCARD_ON_LOAD = "Targets";
public static final int FAIL_PENDING = -1; // By Claude on 05/07/2026: motion sentinel — tile tracked but not yet processed by LMA public static final int FAIL_PENDING = -1; // By Claude on 05/07/2026: motion sentinel — tile tracked but not yet processed by LMA
public static final int FAIL_NONE = 0; public static final int FAIL_NONE = 0;
......
...@@ -419,7 +419,7 @@ public class CuasRanging { ...@@ -419,7 +419,7 @@ public class CuasRanging {
saveTargetStats(targets); // final double [][][] targets_single) { saveTargetStats(targets); // final double [][][] targets_single) {
} }
} }
System.out.print((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+": Ranging done"));
if (generate_output) { if (generate_output) {
cuasMotion.generateExtractFilterMovingTargets( // move parameters to clt_parameters cuasMotion.generateExtractFilterMovingTargets( // move parameters to clt_parameters
......
...@@ -796,6 +796,10 @@ min_str_neib_fpn 0.35 ...@@ -796,6 +796,10 @@ 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 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_accum_base = true; // Accumulate centered targets with base "exposure" public boolean cuas_accum_base = true; // Accumulate centered targets with base "exposure"
public boolean cuas_accum_boosted = true; // Accumulate centered targets with boosted "exposure" public boolean cuas_accum_boosted = true; // Accumulate centered targets with boosted "exposure"
...@@ -2721,10 +2725,16 @@ min_str_neib_fpn 0.35 ...@@ -2721,10 +2725,16 @@ 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.addCheckbox ("Accumulate phasae 1 base exposure", this.cuas_phase1_base,
"Accumulate non-centered targets (phase 1) with base \"exposure\".");
gd.addCheckbox ("Accumulate phase 1 boosted exposure", this.cuas_phase1_boosted,
"Accumulate non-centered targets (phASE 1) with boosted \"exposure\".");
gd.addCheckbox ("Accumulate tracking base exposure", this.cuas_accum_base, gd.addCheckbox ("Accumulate tracking base exposure", this.cuas_accum_base,
"Accumulate centered targets with base \"exposure\"."); "Accumulate centered targets with base \"exposure\".");
gd.addCheckbox ("Accumulate tracking boosted exposure", this.cuas_accum_boosted, gd.addCheckbox ("Accumulate tracking boosted exposure", this.cuas_accum_boosted,
"Accumulate centered targets with boosted \"exposure\"."); "Accumulate centered targets with boosted \"exposure\".");
gd.addNumericField("Boost pairs for weak targets", this.cuas_boost_mstr, 5,8,"", gd.addNumericField("Boost pairs for weak targets", this.cuas_boost_mstr, 5,8,"",
"Scale corr_pairs if motion strength is below, regardless of speed."); "Scale corr_pairs if motion strength is below, regardless of speed.");
gd.addNumericField("Never boost stronger", this.cuas_boost_xstr, 5,8,"", gd.addNumericField("Never boost stronger", this.cuas_boost_xstr, 5,8,"",
...@@ -4420,6 +4430,8 @@ min_str_neib_fpn 0.35 ...@@ -4420,6 +4430,8 @@ 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_phase1_base = gd.getNextBoolean();
this.cuas_phase1_boosted = gd.getNextBoolean();
this.cuas_accum_base = gd.getNextBoolean(); this.cuas_accum_base = gd.getNextBoolean();
this.cuas_accum_boosted = gd.getNextBoolean(); this.cuas_accum_boosted = gd.getNextBoolean();
this.cuas_boost_mstr = gd.getNextNumber(); this.cuas_boost_mstr = gd.getNextNumber();
...@@ -5738,6 +5750,8 @@ min_str_neib_fpn 0.35 ...@@ -5738,6 +5750,8 @@ 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_phase1_base", this.cuas_phase1_base+""); // 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
properties.setProperty(prefix+"cuas_accum_boosted", this.cuas_accum_boosted+""); // boolean properties.setProperty(prefix+"cuas_accum_boosted", this.cuas_accum_boosted+""); // boolean
properties.setProperty(prefix+"cuas_boost_mstr", this.cuas_boost_mstr+""); // double properties.setProperty(prefix+"cuas_boost_mstr", this.cuas_boost_mstr+""); // double
...@@ -6992,8 +7006,10 @@ min_str_neib_fpn 0.35 ...@@ -6992,8 +7006,10 @@ 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_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_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"));
if (properties.getProperty(prefix+"cuas_accum_boosted")!=null) this.cuas_accum_boosted=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_accum_boosted")); if (properties.getProperty(prefix+"cuas_accum_boosted")!=null) this.cuas_accum_boosted=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_accum_boosted"));
if (properties.getProperty(prefix+"cuas_boost_mstr")!=null) this.cuas_boost_mstr=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_mstr")); if (properties.getProperty(prefix+"cuas_boost_mstr")!=null) this.cuas_boost_mstr=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_mstr"));
if (properties.getProperty(prefix+"cuas_boost_xstr")!=null) this.cuas_boost_xstr=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_xstr")); if (properties.getProperty(prefix+"cuas_boost_xstr")!=null) this.cuas_boost_xstr=Double.parseDouble(properties.getProperty(prefix+"cuas_boost_xstr"));
if (properties.getProperty(prefix+"cuas_corr_offset")!=null) this.cuas_corr_offset=Integer.parseInt(properties.getProperty(prefix+"cuas_corr_offset")); if (properties.getProperty(prefix+"cuas_corr_offset")!=null) this.cuas_corr_offset=Integer.parseInt(properties.getProperty(prefix+"cuas_corr_offset"));
...@@ -8263,6 +8279,8 @@ min_str_neib_fpn 0.35 ...@@ -8263,6 +8279,8 @@ 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_phase1_base = this.cuas_phase1_base;
imp.cuas_phase1_boosted = this.cuas_phase1_boosted;
imp.cuas_accum_base = this.cuas_accum_base; imp.cuas_accum_base = this.cuas_accum_base;
imp.cuas_accum_boosted = this.cuas_accum_boosted; imp.cuas_accum_boosted = this.cuas_accum_boosted;
imp.cuas_boost_mstr = this.cuas_boost_mstr; imp.cuas_boost_mstr = this.cuas_boost_mstr;
......
...@@ -37,8 +37,10 @@ import java.nio.file.Files; ...@@ -37,8 +37,10 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
...@@ -9038,7 +9040,9 @@ if (debugLevel > -100) return true; // temporarily ! ...@@ -9038,7 +9040,9 @@ if (debugLevel > -100) return true; // temporarily !
if (stop_now) { if (stop_now) {
break; // will still generate videos break; // will still generate videos
} }
System.out.println((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+": Sequence done."));
} // for (int nseq = 0; nseq < num_seq; nseq++) { } // for (int nseq = 0; nseq < num_seq; nseq++) {
System.out.println((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+": All sequences done"));
// combine videos if generated // combine videos if generated
if ((video_sets_list.size() > 1) && if ((video_sets_list.size() > 1) &&
......
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