Commit 3357ad5b authored by Andrey Filippov's avatar Andrey Filippov

Another bug - new centered targets inherited fail==0, not NaN for

non-centered
parent 5fed114d
......@@ -469,664 +469,6 @@ public class CuasMotion {
return;
}
/*
public static boolean testCuasMotion(
ImagePlus imp_sel,
CLTParameters clt_parameters,
QuadCLT parentCLT,
int debugLevel) {
int framecent = 180;
int corr_offset = clt_parameters.imp.cuas_corr_offset;
int corr_pairs = clt_parameters.imp.cuas_corr_pairs;
double cuas_fat_zero = clt_parameters.imp.cuas_fat_zero;
double cuas_cent_radius = clt_parameters.imp.cuas_cent_radius;
int cuas_n_recenter = clt_parameters.imp.cuas_n_recenter;
double cuas_rstr = clt_parameters.imp.cuas_rstr;// 0.003; // clt_parameters.imp.rln_sngl_rstr; // FIXME: ADD
boolean smooth = clt_parameters.imp.cuas_smooth; // true;
GenericJTabbedDialog gd = new GenericJTabbedDialog("Motion detect parameters");
gd.addNumericField("Center frame", framecent, 0, 5, "frame", "Center frame");
gd.addNumericField("Number of pairs", corr_pairs, 0, 3, "", "The number of correlation pairs to accumulate.");
gd.addNumericField("Pairs offset", corr_offset, 0, 3, "", "Offset between the correlation pairs");
gd.addCheckbox ("Smooth weights", smooth, "Apply cosine weights when averaging a sequence of correlation pairs.");
gd.addNumericField("Fat zero", cuas_fat_zero, 7, 10, "", "Fat zero for TD->PD conversion");
gd.addNumericField("Center radius", cuas_cent_radius, 3, 5, "pix", "Center radius");
gd.addNumericField("Number of recenters", cuas_n_recenter, 0, 5, "", "Number of centroid re-center iterations");
gd.addNumericField("Relative strength", cuas_rstr, 3, 5, "x", "Minimal relative strength of the 2D correlation");
gd.showDialog();
if (gd.wasCanceled())
return false;
framecent = (int) gd.getNextNumber();
corr_pairs = (int) gd.getNextNumber();
corr_offset = (int) gd.getNextNumber();
smooth = gd.getNextBoolean();
cuas_fat_zero = gd.getNextNumber();
cuas_cent_radius = gd.getNextNumber();
cuas_n_recenter = (int) gd.getNextNumber();
cuas_rstr = gd.getNextNumber();
final boolean batch_mode = false;
int frame0 = framecent - (corr_offset + corr_pairs)/2;
int frame1 = framecent + (corr_offset - corr_pairs)/2;
String suffix_param = "-"+framecent+"-"+corr_offset+"-"+corr_pairs;
String dbg_suffix = imp_sel.getTitle()+suffix_param;
if (parentCLT.getTileProcessor() == null) {
parentCLT.setTiles (imp_sel, // set global tp.tilesX, tp.tilesY
parentCLT.getNumSensors(), // tp.getNumSensors(),
clt_parameters,
QuadCLT.THREADS_MAX); // where to get it? Use instance member
}
CuasMotion cuasMotion = new CuasMotion (
clt_parameters, // CLTParameters clt_parameters,
null, // scene_titles, // String [] scene_titles,
parentCLT, // QuadCLT parentCLT,
null, // uasLogReader, // UasLogReader uasLogReader,
debugLevel); // int debugLevel)
int num_slices = imp_sel.getStack().getSize();
float [][] fpixels = new float[num_slices][];
for (int nslice = 0; nslice < fpixels.length; nslice++) {
fpixels[nslice] = (float[]) imp_sel.getStack().getPixels(nslice+1);
}
int corr_ra_step = 1;
TDCorrTile [] tdCorrTiles = cuasMotion.correlatePairs(
clt_parameters, // CLTParameters clt_parameters,
fpixels, // float [][] fpixels,
frame0, // int frame0,
frame1, // int frame1,
corr_pairs, // int frame_len,
corr_ra_step, // int corr_ra_step,
smooth, // boolean smooth, // use cosine mask
true, // batch_mode, // final boolean batch_mode,
dbg_suffix, // final String dbg_suffix, // for image_names
debugLevel); // int debugLevel)
// convert to pixel domain and display
double [][] corr_tiles_pd = cuasMotion.convertTDtoPD(
tdCorrTiles, // final TDCorrTile [] tiles,
0xFE, // final int corr_type, // 0xFE
cuas_fat_zero, // final double gpu_fat_zero,
debugLevel); // final int debug_level
double [][] vector_field = TDCorrTile.getMismatchVector( // full tiles in gpu (512*512)
corr_tiles_pd, // final double[][] tiles,
cuas_rstr, // double rmax,
cuas_cent_radius, // final double centroid_radius, // 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
cuas_n_recenter, // final int n_recenter); // re-center window around new maximum. 0 -no refines (single-pass)
true); // final boolean calc_fraction ){ // calculate fraction inside center circle
final int corr_size = 2 * GPUTileProcessor.DTT_SIZE -1;
boolean show_vector_field = true; // (debugLevel>100); // true;
boolean show_2d_correlations = true; // (debugLevel>0); // true;
if (show_2d_correlations) {
double [][] dbg_2d_corrs = ImageDtt.corr_partial_dbg( // not used in lwir
new double [][][] {corr_tiles_pd}, // final double [][][] corr_data, // [layer][tile][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
cuasMotion.tilesX, // final int tilesX,
corr_size, //final int corr_size, // 15
clt_parameters.corr_border_contrast, // final double border_contrast,
debugLevel); // final int globalDebugLevel)
String [] dbg_titles= {"raw"}; // ,"neibs"};
ShowDoubleFloatArrays.showArrays(
dbg_2d_corrs,
cuasMotion.tilesX * (corr_size + 1),
cuasMotion.tilesY * (corr_size + 1),
true,
imp_sel.getTitle()+"-corr2d"+suffix_param, // "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
dbg_titles);
}
if (show_vector_field) {
// double [][] dbg_vf = new double [3 * vector_field.length][cuasMotion.tilesX * cuasMotion.tilesY];
double [][] dbg_vf = new double [4][cuasMotion.tilesX * cuasMotion.tilesY];
String [] dbg_titles = new String[dbg_vf.length];
dbg_titles [0] = "vX";
dbg_titles [1] = "vY";
dbg_titles [2] = "conf";
dbg_titles [3] = "frac";
for (int i = 0; i < dbg_vf.length; i++) {
Arrays.fill(dbg_vf[i], Double.NaN);
}
for (int t=0; t<dbg_vf[0].length; t++) {
if (vector_field[t] != null) {
for (int k = 0; k < dbg_titles.length; k++) {
dbg_vf[k][t] = vector_field[t][k];
}
}
}
ShowDoubleFloatArrays.showArrays(
dbg_vf,
cuasMotion.tilesX,
cuasMotion.tilesY,
true,
imp_sel.getTitle()+"-vector_field"+suffix_param,
dbg_titles);
}
// return vector_field; // corr_tiles;
return true;
}
public static boolean testCuasScanMotion(
ImagePlus imp_sel,
CLTParameters clt_parameters,
QuadCLT parentCLT,
int debugLevel) {
String image_name = imp_sel.getTitle().substring(0,17);
parentCLT.setImageName(image_name);
String x3d_path = parentCLT.getX3dDirectory();
System.out.println ("Model directory = "+x3d_path);
int corr_pairs = clt_parameters.imp.cuas_corr_pairs;
int corr_offset = clt_parameters.imp.cuas_corr_offset;
int precorr_ra = clt_parameters.imp.cuas_precorr_ra;
int corr_ra_step = clt_parameters.imp.cuas_corr_step;
// int temporal_um = clt_parameters.imp.cuas_temporal_um;
// double tum_threshold = clt_parameters.imp.cuas_tum_threshold;// 0.003; // clt_parameters.imp.rln_sngl_rstr; // FIXME: ADD
double fat_zero = clt_parameters.imp.cuas_fat_zero;
double cent_radius = clt_parameters.imp.cuas_cent_radius;
int n_recenter = clt_parameters.imp.cuas_n_recenter;
double rstr = clt_parameters.imp.cuas_rstr;// 0.003; // clt_parameters.imp.rln_sngl_rstr; // FIXME: ADD
double speed_min = clt_parameters.imp.cuas_speed_min;
double speed_pref = clt_parameters.imp.cuas_speed_pref;
double speed_boost = clt_parameters.imp.cuas_speed_boost;
boolean smooth = clt_parameters.imp.cuas_smooth; // true;
boolean half_step = clt_parameters.imp.cuas_half_step; // true;
int max_range = clt_parameters.imp.cuas_max_range;
int num_cycles = clt_parameters.imp.cuas_num_cycles;
double target_radius = clt_parameters.imp.cuas_target_radius;
double target_strength = clt_parameters.imp.cuas_target_strength;
double [][] target_frac = new double [clt_parameters.imp.cuas_target_frac.length][2];
boolean no_border= clt_parameters.imp.cuas_no_border; // true;
// Moving target LMA
double lma_sigma = clt_parameters.imp.cuas_lma_sigma; // = 3.0;
double wnd_pedestal = clt_parameters.imp.cuas_wnd_pedestal; // = 0.1;
double lma_r0 = clt_parameters.imp.cuas_lma_r0; // = 3.0; //maximum with with overshoot
double lma_ovrsht = clt_parameters.imp.cuas_lma_ovrsht; // = 2.0;
// CUAS Motion LMA parameters
boolean lma_fit_xy= clt_parameters.imp.cuas_lma_fit_xy; // true;
boolean lma_fit_a= clt_parameters.imp.cuas_lma_fit_a; // true;
boolean lma_fit_c= clt_parameters.imp.cuas_lma_fit_c; // true;
boolean lma_fit_r= clt_parameters.imp.cuas_lma_fit_r; // true;
boolean lma_fit_k= clt_parameters.imp.cuas_lma_fit_k; // true;
double lambda = clt_parameters.imp.cuas_lambda; // = 0.1;
double lambda_good = clt_parameters.imp.cuas_lambda_good; // = 0.5;
double lambda_bad = clt_parameters.imp.cuas_lambda_bad; // = 8;
double lambda_max = clt_parameters.imp.cuas_lambda_max; // = 100;
double rms_diff = clt_parameters.imp.cuas_rms_diff; // = 0.001; // relative RMS improvement
int num_iter = clt_parameters.imp.cuas_num_iter; // = 20;
// CUAS Motion LMA filter parameters
double lma_rms = clt_parameters.imp.cuas_lma_rms; // = 1.5; // Maximal RMS, regardless of amplitude
double lma_arms = clt_parameters.imp.cuas_lma_arms; // = 0.06; // Maximal absolute RMS, sufficient for any amplitude
double lma_rrms = clt_parameters.imp.cuas_lma_rrms; // = 0.15; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
double lma_mina = clt_parameters.imp.cuas_lma_mina; // = 1.0; // Minimal A (amplitude)
double lma_maxr = clt_parameters.imp.cuas_lma_maxr; // = 5.0; // Maximal radius (>3.8)
// double lma_minr1 = clt_parameters.imp.cuas_lma_minr1; // = 1.0; // Maximal inner radius
double lma_mink = clt_parameters.imp.cuas_lma_mink; // = 0.0; // Minimal K (overshoot) <0.007
double lma_maxk = clt_parameters.imp.cuas_lma_maxk; // = 5.0; // Minimal K (overshoot) > 3.8
// double lma_a2a = clt_parameters.imp.cuas_lma_a2a; // = 0.7; // Minimal ratio of the maximal pixel to the amplitude
boolean remove_isolated= clt_parameters.imp.cuas_isolated; // true;
double mask_width = clt_parameters.imp.cuas_mask_width; // 9;
double mask_blur = clt_parameters.imp.cuas_mask_blur; // 3;
boolean mask_round = clt_parameters.imp.cuas_mask_round; // false;
int target_type = clt_parameters.imp.cuas_target_type; //0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
double input_range = clt_parameters.imp.cuas_input_range; // 5;
boolean scale2x = clt_parameters.imp.cuas_scale2x; //true;
boolean ra_background = clt_parameters.imp.cuas_ra_background; //true;
int iter_show = clt_parameters.imp.cuas_iter_show; //1; // Maximal enhancement iteration to show intermediate result (0 - none)
boolean corr2d_save_show = clt_parameters.imp.cuas_2d_save_show; //true;
boolean intermed_low = clt_parameters.imp.cuas_intermed_low; //true;
boolean intermed_high = clt_parameters.imp.cuas_intermed_high; //true;
boolean intermed_giga = clt_parameters.imp.cuas_intermed_giga; //false;
boolean save_mono = clt_parameters.imp.cuas_save_mono; //true;
boolean save_color = clt_parameters.imp.cuas_save_color; //true;
boolean save_video = clt_parameters.imp.cuas_save_video; //true;
boolean clean_video = clt_parameters.imp.cuas_clean_video; //true;// save video without any debug information for targets, output in TIFF files. False - same output for video and TIFFs
for (int i = 0; i < target_frac.length; i++) {
if (clt_parameters.imp.cuas_target_frac[i].length >= 2) {
target_frac[i][0] = clt_parameters.imp.cuas_target_frac[i][0];
target_frac[i][1] = clt_parameters.imp.cuas_target_frac[i][1];
} else {
System.out.println("testCuasScanMotion(): wrong format for a pair of strength, fraction values.");
}
}
String data_dir = "/media/elphel/NVME/lwir16-proc/eagle_mountain/linked/movement/selected/13";
//file:///media/elphel/NVME/lwir16-proc/eagle_mountain/linked/movement/selected/12/INPUT-1747803449_165687.tiff-vector_extended-offs20-pairs50-rstr0.01-fz300.0-cr3.0-mr2-ms0.3-sp1.0-2.5.tiff
// gd.addStringField("KML document title", name, 100, "Provide title of the KML file");
// srt_path = gd.getNextString();
boolean save_params = true;
boolean test_lma = false;
while (true) {
GenericJTabbedDialog gd = new GenericJTabbedDialog("Motion scan parameters");
// gd.addNumericField("Center frame", framecent, 0, 5, "frame", "Center frame");
gd.addNumericField("Number of pairs", corr_pairs, 0, 3, "", "The number of correlation pairs to accumulate.");
gd.addNumericField("Pairs offset", corr_offset, 0, 3, "scenes", "Offset between the correlation pairs");
gd.addNumericField("Pre-correlation running average", precorr_ra, 0,3,"scenes", "Smoothing input data by running average before correlation for motion vectors calculations. Target extraction wil still use individual scenes.");
gd.addNumericField("Correlation step after RA", corr_ra_step, 0,3,"scenes", "Decimate correlations after running average");
gd.addCheckbox ("Smooth weights", smooth, "Apply cosine weights when averaging a sequence of correlation pairs.");
gd.addCheckbox ("Half scan step", half_step, "Reduce step for motion detection = offset/2, if false = offset.");
gd.addNumericField("Fat zero", fat_zero, 7, 10, "", "Fat zero for TD->PD conversion");
gd.addNumericField("Center radius", cent_radius, 3, 5, "pix", "Center radius");
gd.addNumericField("Number of recenters", n_recenter, 0, 5, "", "Number of centroid re-center iterations");
gd.addNumericField("Relative strength", rstr, 3, 5, "x", "Minimal absoute strength of the 2D correlation (negative - relative)");
gd.addNumericField("Minimal speed", speed_min, 5,8,"ppr", "Minimal target speed in pixels per range (per cuas_corr_offset).");
gd.addNumericField("Preferable speed", speed_pref, 5,8,"ppr", "Boost effective strength when speed is above this.");
gd.addNumericField("Maximal speed boost", speed_boost, 5,8,"", "Maximal speed-caused effective strength boost.");
gd.addNumericField("Local max range", max_range, 0,3,"", "While filtering local correlation maximums: 1 - 3x3 neighbors, 2 - 5x5 ones.");
gd.addNumericField("Number of enhancement cycles", num_cycles, 0,3,"","Number of cycles of testing and removing bad targets from compoetition with weaker neighbors.");
gd.addNumericField("Target radius", target_radius, 5,8,"pix","Target radius, also used to calculate fraction of totals inside (windowed) to all positive values.");
gd.addNumericField("Minimal target strength", target_strength, 5,8,"","Minimal value of the target image.");
gd.addStringField ("Fraction for strengths", IntersceneMatchParameters.double2dToString(target_frac), 100,
"Variable number of (strength, fraction) pairs separated by \":\". Each pair of strength, minimal fraction is separated by \",\".");
gd.addCheckbox ("Target not on the tile edge", no_border, "Exclude targets with centers on the edge of 16x16 tiles.");
gd.addMessage("=== Moving target LMA ===");
gd.addNumericField("Weight Gaussian sigma", lma_sigma, 5,8,"pix",
"Weights to emphasize maximum center area when fitting.");
gd.addNumericField("Weight pedestal", wnd_pedestal, 5,8,"",
"Add constant to Gaussian weights.");
gd.addNumericField("Target typical radius", lma_r0, 5,8,"pix",
"Typical target radius including negative overshoot (caused by UM filter).");
gd.addNumericField("Target maximum overshoot", lma_ovrsht, 5,8,"",
"Hos much smaller is the first zero than total maximum with overshoot (2.0 - first zero radius 1/2 of the full.");
gd.addMessage("--- Moving target LMA fitting parameters ---");
gd.addCheckbox ("LMA fit X,Y", lma_fit_xy, "Fit target center position.");
gd.addCheckbox ("LMA fit amplitude (strength)", lma_fit_a, "Fit maximum amplitude.");
gd.addCheckbox ("LMA fit offset", lma_fit_c, "Fit out-of-maximum level (offset).");
gd.addCheckbox ("LMA fit radius", lma_fit_r, "Fit target total radius - includes negative overshoot caused by UM filter.");
gd.addCheckbox ("LMA fit overshoot", lma_fit_k, "Fit target overshoot (2.0 - first zero crossing at half radius.");
gd.addNumericField("LMA lambda", lambda, 5,8,"",
"LMA initial lambda.");
gd.addNumericField("Scale lambda after success", lambda_good, 5,8,"",
"Multiply lambda if RMS decreaed.");
gd.addNumericField("Scale lambda after failure", lambda_bad, 5,8,"",
"Multiply lambda if RMS increaed.");
gd.addNumericField("Maximal lambda", lambda_max, 5,8,"",
"Give up if lambda gets higher value.");
gd.addNumericField("Relative RMS improvement", rms_diff, 5,8,"",
"Finish fitting when the relative RMS improvement drops below this value.");
gd.addNumericField("LMA iterations", num_iter, 0,3,"",
"Maximal number of the LMA iterations.");
gd.addMessage("--- Moving target discrimination parameters thresholds ---");
gd.addNumericField("Maximal RMS", lma_rms, 5,8,"",
"Maximal RMS for target that should match always, regardless of the amplitude.");
gd.addNumericField("Maximal sufficient RMS", lma_arms, 5,8,"",
"Maximal sufficient RMS for target. Satisfying any of the sufficient or relative is enough");
gd.addNumericField("Maximal relative RMS", lma_rrms, 5,8,"",
"Maximal relative (to amplitude) RMS for target. Satisfying any of the absolute and relative is sufficient");
gd.addNumericField("Minimal target amplitude", lma_mina, 5,8,"",
"Filter out weak targets.");
gd.addNumericField("Maximal radius", lma_maxr, 5,8,"",
"Maximal target radius including negative overshoot.");
gd.addNumericField("Minimal overshoot ratio", lma_mink, 5,8,"",
"Minimal ratio of the overshoot radius to the first 0 radius (typical 1.0).");
gd.addNumericField("Maximal overshoot ratio", lma_maxk, 5,8,"",
"Maximal ratio of the overshoot radius to the first 0 radius (typical 3.0).");
gd.addCheckbox ("Remove single-frame targets", remove_isolated,
"Remove targets that do not have neighbors before/afte.");
gd.addNumericField("Mask diameter", mask_width, 5,8,"pix",
"Taget mask to replace static background with moving target.");
gd.addNumericField("Mask transition width", mask_blur, 5,8,"pix",
"Transition between opaque and transparent mask.");
gd.addCheckbox ("Mask round", mask_round,
"Use round mask. Unchesked - use sharp square mask without any transition.");
gd.addNumericField("Targets icon type", target_type, 0,3,"",
"0 - unknown (dashed square), 1 - known (square), 2 - friend (circle), 3 - foe (diamond).");
gd.addNumericField("Image range", input_range, 5,8,"10mK",
"Dispaly pixel values range (1.0 ~= 10 mK).");
gd.addCheckbox ("Scale images twice", scale2x,
"Scale imges to 1280x1024 for higher annotation quality.");
gd.addCheckbox ("Smooth background with runnong average", ra_background,
"Apply running average to the background of the moving targets (false - use high-noise no-averaged images.");
gd.addMessage("=== Saving intermediate and final images and video ===");
gd.addNumericField("Maximal iteration to save/show", iter_show, 0,3,"",
"Maximal enhancement iteration to show intermediate result (0 - none).");
gd.addCheckbox ("Save/show 2D correlations", corr2d_save_show,
"Save and optionally show 2D correlations.");
gd.addCheckbox ("Save tile-resolution intermediate images", intermed_low,
"Save intermediate vector fields and target coordinates from the LMA (80x64 layers).");
gd.addCheckbox ("Save pixel-resolution intermediate images",intermed_high,
"Save pixel-resolution accumulated images (640x512).");
gd.addCheckbox ("Save gigabyte files", intermed_giga,
"Save pixel-resolution huge files, such as hyperstack comparison.");
gd.addCheckbox ("Save monochrome targets+background", save_mono,
"Save 32-bit monochrome targets+background Tiffs (before optional scaling).");
gd.addCheckbox ("Save color targets+background", save_color,
"Save color rendered images (same as videos), optionally scaled.");
gd.addCheckbox ("Save videos", save_video,
"Save video with moving targets.");
gd.addStringField("Data directory", data_dir,100,"Intermediate results directory (to bypass first stages during debugging).");
gd.addMessage("=== Currently some methods use clt_parameters directly, so without saving parameters they will not work! ===");
gd.addCheckbox ("Save_params", save_params, "Save edited parameters");
gd.addCheckbox ("Test LMA", test_lma, "Test LMA from known files instead of normal operation.");
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
corr_pairs = (int) gd.getNextNumber();
corr_offset = (int) gd.getNextNumber();
precorr_ra = (int) gd.getNextNumber();
corr_ra_step = (int) gd.getNextNumber();
smooth = gd.getNextBoolean();
half_step = gd.getNextBoolean();
fat_zero = gd.getNextNumber();
cent_radius = gd.getNextNumber();
n_recenter = (int) gd.getNextNumber();
rstr = gd.getNextNumber();
speed_min = gd.getNextNumber();
speed_pref = gd.getNextNumber();
speed_boost = gd.getNextNumber();
max_range = (int) gd.getNextNumber();
num_cycles = (int) gd.getNextNumber();
target_radius = gd.getNextNumber();
target_strength = gd.getNextNumber();
target_frac = IntersceneMatchParameters.stringToDouble2d(gd.getNextString());
no_border = gd.getNextBoolean();
lma_sigma = gd.getNextNumber();
wnd_pedestal = gd.getNextNumber();
lma_r0 = gd.getNextNumber();
lma_ovrsht = gd.getNextNumber();
lma_fit_xy = gd.getNextBoolean();
lma_fit_a = gd.getNextBoolean();
lma_fit_c = gd.getNextBoolean();
lma_fit_r = gd.getNextBoolean();
lma_fit_k = gd.getNextBoolean();
lambda = gd.getNextNumber();
lambda_good = gd.getNextNumber();
lambda_bad = gd.getNextNumber();
lambda_max = gd.getNextNumber();
rms_diff = gd.getNextNumber();
num_iter = (int) gd.getNextNumber();
lma_rms = gd.getNextNumber();
lma_arms = gd.getNextNumber();
lma_rrms = gd.getNextNumber();
lma_mina = gd.getNextNumber();
lma_maxr = gd.getNextNumber();
lma_mink = gd.getNextNumber();
lma_maxk = gd.getNextNumber();
remove_isolated = gd.getNextBoolean();
mask_width = gd.getNextNumber();
mask_blur = gd.getNextNumber();
mask_round = gd.getNextBoolean();
target_type= (int) gd.getNextNumber();
input_range = gd.getNextNumber();
scale2x = gd.getNextBoolean();
ra_background = gd.getNextBoolean();
iter_show= (int) gd.getNextNumber();
corr2d_save_show = gd.getNextBoolean();
intermed_low = gd.getNextBoolean();
intermed_high = gd.getNextBoolean();
intermed_giga = gd.getNextBoolean();
save_mono = gd.getNextBoolean();
save_color = gd.getNextBoolean();
save_video = gd.getNextBoolean();
data_dir = gd.getNextString();
save_params = gd.getNextBoolean();
test_lma = gd.getNextBoolean();
if (save_params) {
clt_parameters.imp.cuas_corr_offset = corr_offset;
clt_parameters.imp.cuas_corr_pairs = corr_pairs;
clt_parameters.imp.cuas_precorr_ra = precorr_ra;
clt_parameters.imp.cuas_corr_step = corr_ra_step;
clt_parameters.imp.cuas_fat_zero = fat_zero;
clt_parameters.imp.cuas_cent_radius = cent_radius;
clt_parameters.imp.cuas_n_recenter = n_recenter;
clt_parameters.imp.cuas_rstr = rstr;
clt_parameters.imp.cuas_speed_min = speed_min;
clt_parameters.imp.cuas_speed_pref = speed_pref;
clt_parameters.imp.cuas_speed_boost = speed_boost;
clt_parameters.imp.cuas_smooth = smooth;
clt_parameters.imp.cuas_max_range = max_range;
clt_parameters.imp.cuas_num_cycles = num_cycles;
clt_parameters.imp.cuas_half_step = half_step;
clt_parameters.imp.cuas_target_radius = target_radius;
clt_parameters.imp.cuas_target_strength = target_strength;
clt_parameters.imp.cuas_target_frac = new double [target_frac.length][2];
for (int i = 0; i < target_frac.length; i++) {
if (target_frac[i].length >= 2) {
clt_parameters.imp.cuas_target_frac[i][0] = target_frac[i][0];
clt_parameters.imp.cuas_target_frac[i][1] = target_frac[i][1];
} else {
System.out.println("testCuasScanMotion(): 2.wrong format for a pair of strength, fraction values.");
}
}
clt_parameters.imp.cuas_no_border = no_border;
clt_parameters.imp.cuas_lma_sigma = lma_sigma;
clt_parameters.imp.cuas_wnd_pedestal= wnd_pedestal;
clt_parameters.imp.cuas_lma_r0 = lma_r0;
clt_parameters.imp.cuas_lma_fit_xy= lma_fit_xy;
clt_parameters.imp.cuas_lma_fit_a= lma_fit_a;
clt_parameters.imp.cuas_lma_fit_c= lma_fit_c;
clt_parameters.imp.cuas_lma_fit_r= lma_fit_r;
clt_parameters.imp.cuas_lma_fit_k= lma_fit_k;
clt_parameters.imp.cuas_lma_ovrsht = lma_ovrsht;
clt_parameters.imp.cuas_lambda = lambda;
clt_parameters.imp.cuas_lambda_good = lambda_good;
clt_parameters.imp.cuas_lambda_bad = lambda_bad;
clt_parameters.imp.cuas_lambda_max = lambda_max;
clt_parameters.imp.cuas_rms_diff = rms_diff;
clt_parameters.imp.cuas_num_iter = num_iter;
clt_parameters.imp.cuas_lma_rms = lma_rms;
clt_parameters.imp.cuas_lma_arms = lma_arms;
clt_parameters.imp.cuas_lma_rrms = lma_rrms;
clt_parameters.imp.cuas_lma_mina = lma_mina;
clt_parameters.imp.cuas_lma_maxr = lma_maxr;
clt_parameters.imp.cuas_lma_mink = lma_mink;
clt_parameters.imp.cuas_lma_maxk = lma_maxk;
clt_parameters.imp.cuas_isolated = remove_isolated;
clt_parameters.imp.cuas_mask_width = mask_width;
clt_parameters.imp.cuas_mask_blur = mask_blur;
clt_parameters.imp.cuas_mask_round = mask_round;
clt_parameters.imp.cuas_target_type = target_type;
clt_parameters.imp.cuas_input_range = input_range;
clt_parameters.imp.cuas_scale2x = scale2x;
clt_parameters.imp.cuas_ra_background =ra_background;
clt_parameters.imp.cuas_iter_show = iter_show;
clt_parameters.imp.cuas_2d_save_show = corr2d_save_show;
clt_parameters.imp.cuas_intermed_low = intermed_low;
clt_parameters.imp.cuas_intermed_high =intermed_high;
clt_parameters.imp.cuas_intermed_giga =intermed_giga;
clt_parameters.imp.cuas_save_mono = save_mono;
clt_parameters.imp.cuas_save_color = save_color;
clt_parameters.imp.cuas_save_video = save_video;
}
int start_frame = 0;
if (parentCLT.getTileProcessor() == null) {
parentCLT.setTiles (imp_sel, // set global tp.tilesX, tp.tilesY
parentCLT.getNumSensors(), // tp.getNumSensors(),
clt_parameters,
QuadCLT.THREADS_MAX); // where to get it? Use instance member
}
int first_corr = 1; // skip average
int num_scenes = imp_sel.getStack().getSize()- first_corr; // includes average
int seq_length = corr_offset + corr_pairs;
int corr_inc = half_step ? (corr_offset/2) : corr_offset;
int num_corr_samples = (num_scenes - seq_length - start_frame) / corr_inc;
if (debugLevel > -4) {
System.out.println("corr_pairs= "+corr_pairs);
System.out.println("corr_offset= "+corr_offset);
System.out.println("precorr_ra= "+precorr_ra);
System.out.println("corr_ra_step= "+corr_ra_step);
System.out.println("seq_length= "+seq_length);
System.out.println("corr_inc= "+corr_inc);
System.out.println("num_scenes= "+num_scenes);
System.out.println("start_frame= "+start_frame);
System.out.println("num_corr_samples="+num_corr_samples);
System.out.println("rstr= "+rstr);
System.out.println("speed_min= "+speed_min);
System.out.println("speed_pref= "+speed_pref);
System.out.println("speed_boost= "+speed_boost);
System.out.println("fat_zero= "+fat_zero);
System.out.println("max_range= "+max_range);
System.out.println("num_cycles= "+num_cycles);
System.out.println("target_radius= "+target_radius);
System.out.println("target_strength= "+target_strength);
System.out.println("target_frac= "+IntersceneMatchParameters.double2dToString(target_frac));
System.out.println("no_border= "+no_border);
System.out.println("lma_sigma= "+lma_sigma);
System.out.println("wnd_pedestal= "+wnd_pedestal);
System.out.println("lma_r0= "+lma_r0);
System.out.println("lma_ovrsht= "+lma_ovrsht);
System.out.println("lma_fit_xy= "+lma_fit_xy);
System.out.println("lma_fit_a= "+lma_fit_a);
System.out.println("lma_fit_c= "+lma_fit_c);
System.out.println("lma_fit_r= "+lma_fit_r);
System.out.println("lma_fit_k= "+lma_fit_k);
System.out.println("lambda= "+lambda);
System.out.println("lambda_good= "+lambda_good);
System.out.println("lambda_bad= "+lambda_bad);
System.out.println("lambda_max= "+lambda_max);
System.out.println("rms_diff= "+rms_diff);
System.out.println("num_iter= "+num_iter);
System.out.println("lma_rms= "+lma_rms);
System.out.println("lma_arms= "+lma_arms);
System.out.println("lma_rrms= "+lma_rrms);
System.out.println("lma_mina= "+lma_mina);
System.out.println("lma_maxr= "+lma_maxr);
System.out.println("lma_mink= "+lma_mink);
System.out.println("lma_maxk= "+lma_maxk);
System.out.println("remove_isolated= "+remove_isolated);
System.out.println("mask_width= "+mask_width);
System.out.println("mask_blur= "+mask_blur);
System.out.println("mask_round= "+mask_round);
System.out.println("target_type= "+target_type);
System.out.println("input_range= "+input_range);
System.out.println("scale2x= "+scale2x);
System.out.println("ra_background= "+ra_background);
System.out.println("iter_show= "+iter_show);
System.out.println("corr2d_save_show="+corr2d_save_show);
System.out.println("intermed_low= "+intermed_low);
System.out.println("intermed_high= "+intermed_high);
System.out.println("intermed_giga= "+intermed_giga);
System.out.println("save_mono= "+save_mono);
System.out.println("save_color= "+save_color);
System.out.println("save_video= "+save_video);
}
float [][] fpixels = new float[num_scenes][];
String [] scene_titles = new String [num_scenes];
for (int nscene = 0; nscene < fpixels.length; nscene++) {
fpixels[nscene] = (float[]) imp_sel.getStack().getPixels(nscene+first_corr+1);
scene_titles[nscene] = imp_sel.getStack().getSliceLabel(nscene+first_corr+1);
}
String [] slice_titles= new String [num_corr_samples];
for (int nscan = 0; nscan < num_corr_samples; nscan++) {
int frame_cent = start_frame + corr_inc * nscan + seq_length/2; // debug only
slice_titles[nscan] = imp_sel.getStack().getSliceLabel(frame_cent+1+first_corr); // wrong! should be imp_sel.getStack().getSliceLabel(frame_cent+1+first_corr)
}
CuasMotion cuasMotion = new CuasMotion (
clt_parameters, // CLTParameters clt_parameters,
scene_titles, // String [] scene_titles,
parentCLT, // QuadCLT parentCLT,
null, // uasLogReader, // UasLogReader uasLogReader,
debugLevel); // int debugLevel)
String imp_name = imp_sel.getTitle();
imp_name = trimSuffix(imp_name,".tif");
imp_name = trimSuffix(imp_name,".tiff");
data_dir= trimSuffix(data_dir,"/");
boolean batch_mode = true;
if (test_lma) {
String path_vf = "/media/elphel/NVME/lwir16-proc/eagle_mountain/linked/movement/selected/25_r1.5/I-1747803449_165687-vector_field_good-offs20-pairs50-rstr0.01-fz300.0-cr3.0-mr1-ms0.0-sp0.0-sb1.0-tr2.0-ts0.8-tf0.0,0.12:2.5,0.15:5.0,0.25.tiff";
double [][][] vf_sequence = getVectorFieldHyper(path_vf); // String path)
if (vf_sequence == null) {
System.out.println("Failed to motion vectors from "+path_vf);
continue;
}
if (remove_isolated) {
removeShortTargetSequences(
clt_parameters, // CLTParameters clt_parameters,
batch_mode, // final boolean batch_mode,
parentCLT, // QuadCLT parentCLT, //
vf_sequence, // final double [][][] target_sequence,
cuasMotion, // final CuasMotion cuasMotion,
slice_titles, // String [] slice_titles,
debugLevel); // final int debugLevel)
}
generateExtractFilterMovingTargets( // move parameters to clt_parameters
clt_parameters, // CLTParameters clt_parameters,
false, // final boolean video_pass, // if clt_parameters.cuas_clean_video=true, video_pass=0 - output TIFFS, but no video. If video_pass==1 - only video with no debug
batch_mode, // final boolean batch_mode,
parentCLT, // QuadCLT parentCLT, //
// three arrays needed
fpixels, // final float [][] fpixels,
vf_sequence, // final double [][][] vf_sequence, // center tiles (not extended), null /non-null only
// frame0, // final int frame0, // for vector_field[0] // source scene corresponding to the first sequence
cuasMotion, // final CuasMotion cuasMotion,
null, // UasLogReader uasLogReader,
scene_titles, // String [] scene_titles, // recreate slice_titles from scene titles?
slice_titles, // String [] slice_titles,
debugLevel); // final int debugLevel)
continue;
}
processMovingTargets(
clt_parameters, // CLTParameters clt_parameters,
batch_mode, // final boolean batch_mode,
parentCLT, // QuadCLT parentCLT, //
fpixels, // final float [][] fpixels,
null, // String [] scene_titles, // recreate slice_titles from scene titles?
scene_titles, // String [] scene_titles, // recreate slice_titles from scene titles?
debugLevel); // final int debugLevel)
continue;
} // while (true) {
}
*/
public static void printStats(
String s,
boolean all,
......@@ -1797,245 +1139,7 @@ public class CuasMotion {
// fills out additional fields in target_coords
public static void getEffectiveStrengthLMA(
final double [][][] target_sequence, // modifies certain fields (scores)
final double target_strength,
final double [][] target_frac, // pairs - strength, minimal fraction for that strength
final double lma_rms, // = 1.5; // Maximal RMS (should always match, regardless if A)
final double lma_arms, // = 0.06; // Maximal absolute RMS (should match one of cuas_lma_arms OR cuas_lma_rrms (0.484)
final double lma_rrms, // = 0.15; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
final double lma_mina, // = 1.0; // Minimal A (amplitude)
final double lma_maxr, // = 5.0; // Minimal K (overshoot) = 3.0
final double lma_minr1,// = 1.0; // Minimal R1 (radius of positive peak)
final double lma_mink, // = 0.0; // Minimal K (overshoot) = 1.0
final double lma_maxk, // = 5.0; // Minimal K (overshoot) = 3.0
final double lma_a2a,
final double max_mismatch,
final double good_mismatch, //do not add to score if worse
final boolean fail_mismatch,
final double lma_horizon, // horizon as maximal pixel Y
final int tilesX ) {
// if centroid maximum is safely good, ignore lma_a2a ratio
final double SAFE_CENT_MX = 3 * target_strength; // Find a more elegant solution
final int num_seq = target_sequence.length;
final int num_tiles = target_sequence[0].length;
// final double center_scale = 0.5*Math.PI/GPUTileProcessor.DTT_SIZE;
final double center_scale = 0.25*Math.PI/GPUTileProcessor.DTT_SIZE;
final int dbg_tile = -(34 + 34*80);
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++) {
if (ntile == dbg_tile) {
System.out.println("filterTargetsLMA(): ntile = "+ntile);
}
double [] lma_rslts = target_sequence[nSeq][ntile];
if (lma_rslts != null) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_NONE;
double CENT_STR = lma_rslts[CuasMotionLMA.RSLT_CENT_MX];
double CENT_FRAC= lma_rslts[CuasMotionLMA.RSLT_CENT_F];
double A = lma_rslts[CuasMotionLMA.RSLT_A];
double RMSE = lma_rslts[CuasMotionLMA.RSLT_RMS];
double RMSE_A = lma_rslts[CuasMotionLMA.RSLT_RMS_A];
double R1 = lma_rslts[CuasMotionLMA.RSLT_R1];
double MAX2A = lma_rslts[CuasMotionLMA.RSLT_MAX2A];
double Y = (ntile/tilesX +0.5) * GPUTileProcessor.DTT_SIZE + lma_rslts[CuasMotionLMA.RSLT_Y];
double MM_BEFORE = lma_rslts[CuasMotionLMA.RSLT_MISMATCH_BEFORE];
double MM_AFTER = lma_rslts[CuasMotionLMA.RSLT_MISMATCH_AFTER];
double x = lma_rslts[CuasMotionLMA.RSLT_X];
double y = lma_rslts[CuasMotionLMA.RSLT_Y];
double cxy = 1.0;
if ((Math.abs(x) > 0.5*GPUTileProcessor.DTT_SIZE) || (Math.abs(y) > 0.5*GPUTileProcessor.DTT_SIZE)) {
cxy = 0.0;
} else {
double ax = Math.abs(x) - 0.25*GPUTileProcessor.DTT_SIZE;
double ay = Math.abs(x) - 0.25*GPUTileProcessor.DTT_SIZE;
if (ax > 0) {
cxy *= Math.cos(ax * center_scale);
}
if (ay > 0) {
cxy *= Math.cos(ay * center_scale);
}
}
// double cxy= Math.max(0,Math.cos(x * center_scale)) * Math.max(0,Math.cos(y * center_scale));
boolean failed = true;
try_failures: {
// start with centroid tests
if (CENT_STR < target_strength) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_CENT_STR;
break try_failures; // cemtroid maximum is too weak
}
for (double [] frac_pair : target_frac) {
if ((CENT_STR > frac_pair[0]) && (CENT_FRAC < frac_pair[1])) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_CENT_FRAC;
break try_failures; // centroid fraction is too small
}
}
if (lma_rslts[CuasMotionLMA.RSLT_ITERS] < 0) { // fitting has not failed
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_LMA;
break try_failures; // LMA failed
}
if (A < lma_mina) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_A_LOW;
break try_failures; // too weak
}
if (MAX2A < lma_a2a) {
if (CENT_STR < SAFE_CENT_MX) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_ACENT;
break try_failures; // ratio of maximal value to A is too low
}
}
if (RMSE > lma_rms) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_RMSE;
break try_failures; // too high RMSE regardless of A
}
if ((RMSE > lma_arms) && (RMSE_A > lma_rrms)) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_RMSE_R;
break try_failures; // too high RMSE
}
if (lma_rslts[CuasMotionLMA.RSLT_R0] > lma_maxr) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_R0_HIGH;
break try_failures; // Radius is too high
}
if (R1 < lma_minr1) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_R1_LOW;
break try_failures; // Inner radius too small
}
if (lma_rslts[CuasMotionLMA.RSLT_K] < lma_mink) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_K_LOW;
break try_failures; // K is too low
}
if (lma_rslts[CuasMotionLMA.RSLT_K] > lma_maxk) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_K_HIGH;
break try_failures; // K is too high
}
if (fail_mismatch && !(MM_BEFORE <= max_mismatch) && !(MM_AFTER <= max_mismatch)) { // on both ends, handles NaN
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_MISMATCH;
break try_failures; // Mismatch is too high
}
if ((lma_horizon >0) && (Y > lma_horizon)) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_HORIZON;
break try_failures; // below horizon line
}
if (cxy==0) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_FAR;
break try_failures; // below horizon line
}
failed = false; // all tests passed
}
double [] quality_factors = new double [IMPORTANCE_LENGTH];
if (!failed) {
lma_rslts[CuasMotionLMA.RSLT_FAIL] = 0;
double inv_rms = 1.0 / RMSE;
double inv_rms_lim = 1.0 / lma_arms;
double inv_rel_rms = 1.0 / RMSE_A; // A/RMSE;
double inv_rel_rms_lim = 1.0 / lma_rrms;
quality_factors[IMPORTANCE_A] = Math.max(0,(A- lma_mina)/ lma_mina);
quality_factors[IMPORTANCE_RMS] = Math.max(0,(inv_rms - inv_rms_lim)/ inv_rms_lim); // only >0 for small max-es
quality_factors[IMPORTANCE_RMS_A] = Math.max(0,(inv_rel_rms - inv_rel_rms_lim)/ inv_rel_rms_lim); // only >0 for small max-es
if (MM_BEFORE <= good_mismatch) {
quality_factors[IMPORTANCE_MISMATCH] += Math.max(0,(good_mismatch - MM_BEFORE)/good_mismatch); // 0 .. 1
}
if (MM_AFTER <= good_mismatch) {
quality_factors[IMPORTANCE_MISMATCH] += Math.max(0,(good_mismatch - MM_AFTER)/good_mismatch); // 0 .. 1
}
quality_factors[IMPORTANCE_CENTER] = cxy*cxy;
}
// save quality factors
lma_rslts[CuasMotionLMA.RSLT_QA] = quality_factors[IMPORTANCE_A];
lma_rslts[CuasMotionLMA.RSLT_QRMS] = quality_factors[IMPORTANCE_RMS];
lma_rslts[CuasMotionLMA.RSLT_QRMS_A] = quality_factors[IMPORTANCE_RMS_A];
lma_rslts[CuasMotionLMA.RSLT_QMATCH] = quality_factors[IMPORTANCE_MISMATCH];
lma_rslts[CuasMotionLMA.RSLT_QCENTER] = quality_factors[IMPORTANCE_CENTER];
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return;
}
public static int [] getScore(
final double [][][] target_sequence, // modifies certain fields (scores)
final double importance_limit,
final double importance_power, // Raise each factor to this power before combining
final double [] importance, // for now (each - squared?): [0] - Amplitude (A/A0), 1 - RMS (RMS0/RMS), 2 - RRMS((RMS/A0) / (RMS/A)
final int tilesX ) {
double sw = 0;
for (int i = 0; i < importance.length; i++) {
sw += importance[i];
}
for (int i = 0; i < importance.length; i++) {
importance[i]/=sw;
}
// if centroid maximum is safely good, ignore lma_a2a ratio
final int num_seq = target_sequence.length;
final int num_tiles = target_sequence[0].length;
int [] remain = new int [num_seq];
final int dbg_tile = -(34 + 34*80);
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++) {
if (ntile == dbg_tile) {
System.out.println("filterTargetsLMA(): ntile = "+ntile);
}
double [] lma_rslts = target_sequence[nSeq][ntile];
if (lma_rslts != null) {
lma_rslts[CuasMotionLMA.RSLT_QSCORE] = 0; // CuasMotionLMA.FAIL_NONE;
if (lma_rslts[CuasMotionLMA.RSLT_FAIL] == CuasMotionLMA.FAIL_NONE) {
double [] quality_factors = new double [IMPORTANCE_LENGTH];
quality_factors[IMPORTANCE_A] = lma_rslts[CuasMotionLMA.RSLT_QA];
quality_factors[IMPORTANCE_RMS] = lma_rslts[CuasMotionLMA.RSLT_QRMS];
quality_factors[IMPORTANCE_RMS_A] = lma_rslts[CuasMotionLMA.RSLT_QRMS_A];
quality_factors[IMPORTANCE_MISMATCH] = lma_rslts[CuasMotionLMA.RSLT_QMATCH];
quality_factors[IMPORTANCE_CENTER] = lma_rslts[CuasMotionLMA.RSLT_QCENTER];
for (int i = 0; i < importance.length; i++) {
quality_factors[i] = Math.min(quality_factors[i], importance_limit);
}
double quality = 0;
for (int i = 0; i < importance.length; i++) {
if (!Double.isNaN(quality_factors[i])) {
double factor_contrib = Math.pow(quality_factors[i], importance_power);
quality += importance[i] * factor_contrib;
}
}
quality = Math.pow(quality, 1.0/importance_power);
lma_rslts[CuasMotionLMA.RSLT_QSCORE] = quality;
remain[nSeq]++;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return remain;
}
public static double [][] getEffectiveStrengthMV( // calculate tiles effective strength by the motion vectors. Combine with the target LMA?
final double [][][] targets_sequence,
int niter, // save iteration number on failure if >=
......@@ -5886,6 +4990,7 @@ public class CuasMotion {
final double pre_min_a, // pre-filter minimal LMA-A (half finbal?)
final int min_keep, // 2; // keep at least this number of candidates before using cuas_lma_pre_mina filter
final float [][] accum_debug,
final QuadCLT parentCLT, // debug only, maybe null in other cases
final int debugLevel){
// Will not set [RSLT_FAIL] = FAIL_NONE, but it is not final before
// apply masking in centered mode
......@@ -5950,6 +5055,13 @@ public class CuasMotion {
param_select[CuasMotionLMA.INDX_K] = lma_fit_k;
// final int dbg_tile = -(38 + 45 * 80); //(38 + 45 * 80);
final int dbg_seq = 48;
boolean show_dbg = (dbg_tile >= 0) && (parentCLT != null);
final String [] dbg_titles = {"mask","tile","masked","limited","blured","um","um-blured","um-blured-scaled",
"centroid","lma-Y","fX","ymfx","weights"};
double [][] dbg_stack = show_dbg ? new double [dbg_titles.length][] : null;
if ((dbg_stack != null) && (mask_centered != null)) {
dbg_stack [0] = mask_centered.clone();
}
final boolean use_filters = (lmax_flt_hsigma > 0) && (lmax_flt_lsigma > 0) && (lmax_flt_scale > 0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
......@@ -5971,6 +5083,7 @@ public class CuasMotion {
Arrays.fill(accum_debug[nSeq], Float.NaN);
}
for (int ntile = 0; ntile < num_tiles; ntile++) {
boolean dbg_img = (nSeq==dbg_seq) && (dbg_stack != null) && (ntile == dbg_tile);
if (probed_sequence[nSeq][ntile] != null) {
double [] probed_target = probed_sequence[nSeq][ntile].clone();
if ((nSeq==dbg_seq) && (ntile == dbg_tile)) {
......@@ -6005,7 +5118,9 @@ public class CuasMotion {
}
}
}
if (dbg_img) {
dbg_stack [1] = pix_tile.clone();
}
// find absolute maximum (before hacking and masking)
......@@ -6045,6 +5160,9 @@ public class CuasMotion {
pix_tile[i] *= mask_centered[i];
}
}
if (dbg_img) {
dbg_stack [2] = pix_tile.clone();
}
if (sky_mask != null) {
for (int row = 0; row < tile2; row++) {
......@@ -6086,6 +5204,9 @@ public class CuasMotion {
pix_tile_filtered[i] = Math.max(lmax_flt_neglim, pix_tile_filtered[i]);
}
}
if (dbg_img) { // limited by -0.3
dbg_stack [3] = pix_tile_filtered.clone();
}
System.arraycopy(pix_tile_filtered, 0, pix_tile_filtered0, 0, pix_tile_filtered.length);
gb.blurDouble(
pix_tile_filtered, //
......@@ -6094,9 +5215,15 @@ public class CuasMotion {
lmax_flt_hsigma, // double sigmaX,
lmax_flt_hsigma, // double sigmaY,
0.01); // double accuracy)
if (dbg_img) { // blured
dbg_stack [4] = pix_tile_filtered.clone();
}
for (int i = 0; i < pix_tile_filtered.length; i++) {
pix_tile_filtered[i] = pix_tile_filtered0[i] - pix_tile_filtered[i];
}
if (dbg_img) { // UM
dbg_stack [5] = pix_tile_filtered.clone();
}
gb.blurDouble(
pix_tile_filtered, //
tile2,
......@@ -6104,9 +5231,16 @@ public class CuasMotion {
lmax_flt_lsigma, // double sigmaX,
lmax_flt_lsigma, // double sigmaY,
0.01); // double accuracy)
if (dbg_img) { // UM-blured
dbg_stack [6] = pix_tile_filtered.clone();
}
for (int i = 0; i < pix_tile_filtered.length; i++) {
pix_tile_filtered[i] *= lmax_flt_scale;
}
if (dbg_img) { // UM-blured-scaled
dbg_stack [7] = pix_tile_filtered.clone();
}
ntile_amax = TileNeibs.getAmaxTile(
pix_tile_filtered); //double [] data)
}
......@@ -6125,6 +5259,11 @@ public class CuasMotion {
}
}
if (dbg_img) { // UM-blured-scaled
dbg_stack [8] = pix_tile_centroid.clone();
dbg_stack [9] = pix_tile.clone(); // lma
}
double amax_val = pix_tile_centroid[ntile_amax];
double lmax_val = amax_val;
......@@ -6176,7 +5315,11 @@ public class CuasMotion {
use_max, // int imax, // index of the maximum in data[]
false); // boolean debug)
if (mv != null) {
double [] target = probed_target.clone(); // includes motion vectors
double [] target = probed_target.clone(); // includes motion vectors and old Q_* values!
// was a bug (04/08.2026): target[CuasMotionLMA.RSLT_FAIL] should be undefined!
target[CuasMotionLMA.RSLT_FAIL] = Double.NaN;
target[CuasMotionLMA.RSLT_WHEN] = Double.NaN; // just in case
target[CuasMotionLMA.RSLT_CENT_MX] = 0.0;
target[CuasMotionLMA.RSLT_CENT_X] = mv[0];
target[CuasMotionLMA.RSLT_CENT_Y] = mv[1];
......@@ -6205,8 +5348,35 @@ public class CuasMotion {
indx, // int dbg_index,
debugLevel-3); // int debug_level)
target[CuasMotionLMA.RSLT_ITERS] = rslt; // will save -1 (failure) also
if (rslt >= 0) { // negative amplitude (in both senses)-> failure
cuasMotionLMA.setResult(target);
if ((target[CuasMotionLMA.RSLT_A] < 0) || (cuasMotionLMA.getA() < 0)) {
rslt = -1;
target[CuasMotionLMA.RSLT_ITERS] = rslt;
}
}
if (rslt >= 0) {
cuasMotionLMA.setResult(target);
if (dbg_img) { // UM-blured-scaled
dbg_stack [10] = cuasMotionLMA.getFx();
dbg_stack [11] = cuasMotionLMA.getLastYMinusFx();
dbg_stack [12] = cuasMotionLMA.getWeights();
dbg_titles[10] = "fX_"+cuasMotionLMA.getA()+"-"+cuasMotionLMA.getMaxFx();
System.out.println("getACM(): nSeq="+nSeq+", ntile="+ntile+
" indx="+indx+" use_max="+use_max +
" X = " + target[CuasMotionLMA.RSLT_X] +
" Y = " + target[CuasMotionLMA.RSLT_Y] +
" A = " + target[CuasMotionLMA.RSLT_A] +
" R0 = " + target[CuasMotionLMA.RSLT_R0] +
" R1 = " + target[CuasMotionLMA.RSLT_R1] +
" K = " + target[CuasMotionLMA.RSLT_K] +
" C = " + target[CuasMotionLMA.RSLT_C] +
" RMS = " + target[CuasMotionLMA.RSLT_RMS] +
" RMS_A = "+ target[CuasMotionLMA.RSLT_RMS_A] +
" MAX2A = "+ target[CuasMotionLMA.RSLT_MAX2A] +
" ITERS = "+ target[CuasMotionLMA.RSLT_ITERS]);
}
int col = GPUTileProcessor.DTT_SIZE + (int) Math.round(target[CuasMotionLMA.RSLT_X]);
int row = GPUTileProcessor.DTT_SIZE + (int) Math.round(target[CuasMotionLMA.RSLT_Y]);
int pindx = col+row*tile2;
......@@ -6257,6 +5427,16 @@ public class CuasMotion {
}
}
// show image for each lma run
if (dbg_img) {
ImagePlus imp_dbg = ShowDoubleFloatArrays.makeArrays(
dbg_stack, // float[][] pixels,
tile2, // int width,
tile2, // int height,
parentCLT.getImageName()+"-nSeq"+nSeq+"-tile"+ntile+"-indx"+indx+"-max"+use_max+"-cent_"+centered,
dbg_titles); //String [] titles)
parentCLT.saveImagePlusInModelDirectory(imp_dbg);
}
} else { // if (rslt >= 0) {
target[CuasMotionLMA.RSLT_FAIL] = CuasMotionLMA.FAIL_LMA;
if (when >=0) {
......@@ -6270,7 +5450,7 @@ public class CuasMotion {
}// keep_failed
} // if (mv != null) {
}
} // for (int indx = 0; indx < max_candidate.size(); indx++) {
// sort targets_list, descending LMA amplitude, failed after not failed
// Sort descending values at maximal pixels
Collections.sort(targets_list, new Comparator<Integer>() {
......@@ -7846,6 +7026,7 @@ public class CuasMotion {
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
accum_debug, // final float [][] accum_debug,
parentCLT, // final QuadCLT parentCLT, // debug only, maybe null in other cases
debugLevel); // final int debugLevel);
if (accum_debug != null) {
......@@ -7921,7 +7102,8 @@ public class CuasMotion {
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,
niter, // final int when_iter,
debugLevel); // final int debugLevel);
if (debugLevel > -4) {
System.out.println("Added "+num_new+" new tiles as good/bad");
......@@ -8161,6 +7343,7 @@ public class CuasMotion {
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
accum_debug, // final float [][] accum_debug,
parentCLT, // final QuadCLT parentCLT, // debug only, maybe null in other cases
debugLevel); // final int debugLevel);
if (accum_debug != null) {
......@@ -8244,7 +7427,8 @@ public class CuasMotion {
targets_new_multi, // final double [][][] new_sequence,
// add just one best here?
1, // final int num_best, // if >0, limit number of best results to add
niter); // final int when_iter,
niter, // final int when_iter,
debugLevel); // final int debugLevel);
if (debugLevel > -4) {
System.out.println("Added "+num_new+" new tiles as good/bad at iteration "+niter+".");
......@@ -8307,16 +7491,16 @@ public class CuasMotion {
final int debugLevel){
final boolean use_motion = (motion_sequence != null) ? use_motion_in : false;
final boolean select_new = (motion_sequence != null) ? select_new_in : false;
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 = (debugLevel >0) ?(38+45*80) : -1;
final int dbg_seq0 = (debugLevel >0) ? -13: -1;
final int dbg_seq1 = (debugLevel >0) ? -14: -1;
final int dbg_tile = debug_now ?(12+23*80) : -1;
final int dbg_seq0 = debug_now ? 47: -1;
final int dbg_seq1 = debug_now ? 49: -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);
......@@ -8542,13 +7726,13 @@ public class CuasMotion {
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) {
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) {
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("target_sequence_multi["+nSeq+"]["+ntile+"]["+filter5[nSeq][ntile]+"]["+CuasMotionLMA.RSLT_CENTERED+"] ="+
target_sequence_multi[nSeq][ntile][filter5[nSeq][ntile]][CuasMotionLMA.RSLT_CENTERED]);
}
......@@ -8803,7 +7987,7 @@ public class CuasMotion {
final int num_seq = target_sequence_multi.length;
final int num_tiles = target_sequence_multi[0].length;
int [] remain = new int [num_seq];
final int dbg_tile = -(34 + 34*80);
final int dbg_tile = -(12 + 23*80);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
......@@ -8867,9 +8051,14 @@ public class CuasMotion {
final double [][][][] target_sequence_multi, // will only process non-nulls here
final double [][][][] new_sequence_multi,
final int num_best, // if >0, limit number of best results to add
final int when_iter) { // , final boolean overwrite) {
final int when_iter,
final int debugLevel) {
final int num_seq = target_sequence_multi.length;
final int num_tiles = target_sequence_multi[0].length;
boolean debug_now = (debugLevel > 5); // NEVER
final int dbg_tile = debug_now ?(12+23*80) : -1;
final int dbg_seq0 = debug_now ? 47: -1;
final int dbg_seq1 = debug_now ? 49: -1;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger anew = new AtomicInteger(0);
......@@ -8880,6 +8069,9 @@ public class CuasMotion {
for (int ntile = 0; ntile < num_tiles; ntile++) { // if (target_sequence[nSeq][ntile] != null) {
double [][] tg = target_sequence_multi[nSeq][ntile];
double [][] ns = new_sequence_multi[nSeq][ntile];
if ((ntile == dbg_tile) && (nSeq >= dbg_seq0) && (nSeq <= dbg_seq1)) {
System.out.println("addNewResults()): ntile="+ntile+", nSeq="+nSeq);
}
if ((tg != null) || (ns != null)) {
if (tg == null) tg = new double [0][];
if (ns == null) ns = new double [0][];
......
......@@ -299,14 +299,15 @@ public class CuasMotionLMA {
public void setResult(double [] rslt) {
rslt[RSLT_X] = getCenter()[0];
rslt[RSLT_Y] = getCenter()[1];
rslt[RSLT_A] = getA();
// rslt[RSLT_A] = getA();
rslt[RSLT_A] = getMaxFx(); // maximum of fx, getA() may be much larger!
rslt[RSLT_R0] = getR0();
rslt[RSLT_R1] = getR0() / ((getK()>1) ? getK() : 1.0);
rslt[RSLT_K] = getK();
rslt[RSLT_C] = getC();
rslt[RSLT_RMS] = getRMS();
rslt[RSLT_RMS_A] = getRMS()/getA();
rslt[RSLT_MAX2A] = max_val/getA(); // ratio of maximal value to LMA amplitude
rslt[RSLT_RMS_A] = getRMS()/rslt[RSLT_A]; // getA();
rslt[RSLT_MAX2A] = max_val/rslt[RSLT_A]; // getA(); // ratio of maximal value to LMA amplitude
rslt[RSLT_ITERS] = getIters();
return;
}
......@@ -750,6 +751,7 @@ public class CuasMotionLMA {
return err;
}
private double [][] getFxDerivsDelta(
double [] vector,
final double delta,
......@@ -774,7 +776,29 @@ public class CuasMotionLMA {
return jt;
}
public double getMaxFx() {
double [] fx = getFx();
double mfx = Double.NaN;
for (double d:fx) {
if (!(d <= mfx)) {
mfx = d;
}
}
return mfx;
}
public double [] getFx() {
return getFxDerivs(
full_vector, // final double [] vector,
null, // final double [][] jt, // should be null or initialized with [vector.length][]
-10); // final int debug_level)
}
public double [] getLastYMinusFx() {
return last_ymfx;
}
public double [] getWeights() {
return weights;
}
private double [] getFxDerivs(
final double [] vector,
......
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